From fa64de382f15979b40b18a3d2cc9359c412789b4 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 21 Apr 2020 14:56:58 +0200 Subject: [PATCH 001/237] Fixes an occasional bug --- karaf-assembly/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/karaf-assembly/build.gradle b/karaf-assembly/build.gradle index c9b56c9cc..0db13cd78 100644 --- a/karaf-assembly/build.gradle +++ b/karaf-assembly/build.gradle @@ -43,6 +43,10 @@ parsePom.inputs.property('karafVersion', libraryVersions.karaf) task assembleKaraf(type: CrossPlatformExec) { commandLine "./mvnw", "--no-transfer-progress", "clean", "package" } +// Sometimes required to fix an error caused by a non-existing folder (maybe caused by mvn clean) +assembleKaraf.doLast { + mkdir("${project.buildDir}/classes/kotlin/test") +} assembleKaraf.dependsOn(parsePom) jar.dependsOn(assembleKaraf) From f43876ef204dcfcb5bed44fb894e3931b11ba344 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 21 Apr 2020 16:41:55 +0200 Subject: [PATCH 002/237] Added camel-jsonpath feature, features build.gradle cleanup --- karaf-features-ids/build.gradle | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/karaf-features-ids/build.gradle b/karaf-features-ids/build.gradle index 31837db71..3231dbea3 100644 --- a/karaf-features-ids/build.gradle +++ b/karaf-features-ids/build.gradle @@ -38,7 +38,7 @@ dependencies { karaf { features { - xsdVersion = '1.2.0' + xsdVersion = '1.3.0' // it seems to be best practice to include the version in the feature repository as well name = "ids-${project.version}" version = project.version @@ -54,15 +54,12 @@ karaf { description = 'IDS Feature' // only specifiy the dependencies that will be provided by bundles, the rest will be specified via features - //noinspection GroovyAssignabilityCheck configurations(*project.ext.bundleConfigurations) // standard feature, but we need to explicitly state it here so that it gets installed in our bare Karaf - //noinspection GroovyAssignabilityCheck feature 'jetty' // CXF for REST APIs - //noinspection GroovyAssignabilityCheck feature 'cxf-jaxrs' feature 'cxf-jackson' @@ -71,30 +68,21 @@ karaf { Notice: This should actually be a conditional dependency, only if shell is available. however the karaf assemble plugin does not seem to resolve these conditions during packaging. */ - //noinspection GroovyAssignabilityCheck feature 'cxf-commands' // For Web Application Bundles, such as our WebConsole - //noinspection GroovyAssignabilityCheck feature 'war' - // Camel for routing - //noinspection GroovyAssignabilityCheck - feature 'camel-jackson' - //noinspection GroovyAssignabilityCheck - feature 'camel-milo' - //noinspection GroovyAssignabilityCheck - feature 'camel-cxf' - //noinspection GroovyAssignabilityCheck - feature 'camel-ahc' - //noinspection GroovyAssignabilityCheck + // Features for Apache Camel routing + feature 'camel-jackson' + feature 'camel-milo' + feature 'camel-cxf' + feature 'camel-ahc' feature 'camel-http' - //noinspection GroovyAssignabilityCheck feature 'camel-jetty' - //noinspection GroovyAssignabilityCheck feature 'camel-paho' - //noinspection GroovyAssignabilityCheck //feature 'camel-mqtt' + feature 'camel-jsonpath' // start our bundles a lit bit later bundle ('de.fhg.aisec.ids') { From d951f8347e642f571403c0ea63fa981cf86dd236 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 23 Apr 2020 17:37:08 +0200 Subject: [PATCH 003/237] Fix maven URLs --- .../src/main/resources/etc/org.ops4j.pax.url.mvn.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg b/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg index 6ab1cc8ed..b675f9cb8 100644 --- a/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg +++ b/karaf-assembly/src/main/resources/etc/org.ops4j.pax.url.mvn.cfg @@ -16,8 +16,8 @@ org.ops4j.pax.url.mvn.useFallbackRepositories=false # Remote repositories that are used when resolution of "org.ops4j.pax.url.mvn.defaultRepositories" fails org.ops4j.pax.url.mvn.repositories= \ - http://repo1.maven.org/maven2@id=central, \ - http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ + https://repo1.maven.org/maven2@id=central, \ + https://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases # From 6058877687ebd2c8b2d7c285f7d9ce4a6379a5a8 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 23 Apr 2020 18:09:36 +0200 Subject: [PATCH 004/237] Fixed PaxExam integration testing --- karaf-assembly/build.gradle | 76 +++++++++---- karaf-assembly/pom.template.xml | 2 +- .../ids/webconsole/api/AssemblyTestIT.java | 100 ++++++++---------- libraryVersions.yaml | 8 +- 4 files changed, 105 insertions(+), 81 deletions(-) diff --git a/karaf-assembly/build.gradle b/karaf-assembly/build.gradle index 0db13cd78..1a668482d 100644 --- a/karaf-assembly/build.gradle +++ b/karaf-assembly/build.gradle @@ -1,19 +1,17 @@ dependencies { - testImplementation(project(':ids-api')) { transitive = false } + testImplementation(project(":ids-api")) { transitive = false } - osgiCore group: 'org.apache.felix', name: 'org.apache.felix.framework', version: libraryVersions.felixFramework - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - testImplementation group: 'org.apache.karaf.features', name: 'org.apache.karaf.features.core', version: libraryVersions.karaf -} + osgiCore group: "org.apache.felix", name: "org.apache.felix.framework", version: libraryVersions.felixFramework + osgiCore group: "org.osgi", name: "osgi.cmpn", version: libraryVersions.osgiCompendium -/* -Now this is tricky. We need to build a custom assembly of karaf with a few features: -- included ids feature -- deactivated all other repos, basically make it being 'offline' -- add a bunch of configuration files in etc (although we need to re-verify, which of them are really necessary + testImplementation group: "org.apache.karaf.itests", name: "common", version: libraryVersions.karaf -Since gradle still has no karaf-assembly plugin we need to do this using maven (meh!) -*/ + testImplementation group: "org.apache.karaf", name: "apache-karaf", version: libraryVersions.karaf, ext: "pom" + testImplementation group: "org.awaitility", name: "awaitility", version: libraryVersions.awaitility + testImplementation group: "org.apache.servicemix.bundles", name: "org.apache.servicemix.bundles.hamcrest", + version: libraryVersions.servicemixHamcrest + testImplementation group: "javax.annotation", name: "javax.annotation-api", version: libraryVersions.javaxAnnotation +} static def getBrandingAligned(String branding, String space = "\\u0020") { int BRANDING_WIDTH = 84 @@ -28,18 +26,25 @@ static def getBrandingAligned(String branding, String space = "\\u0020") { task parsePom(type: Copy) { from (project.projectDir) { - include 'pom.template.xml' + include "pom.template.xml" } - expand('projectVersion': project.version, 'karafVersion': libraryVersions.karaf, 'paxVersion': libraryVersions.pax, - 'brandingFirst': getBrandingAligned("Trusted Connector Console (${project.version}), " + + expand("projectVersion": project.version, "karafVersion": libraryVersions.karaf, "paxVersion": libraryVersions.pax, + "brandingFirst": getBrandingAligned("Trusted Connector Console (${project.version}), " + "Apache Karaf (${libraryVersions.karaf})"), - 'brandingSecond': getBrandingAligned("Fraunhofer AISEC ${new Date()[Calendar.YEAR].toString()}")) - rename 'pom.template.xml', 'pom.xml' + "brandingSecond": getBrandingAligned("Fraunhofer AISEC ${new Date()[Calendar.YEAR].toString()}")) + rename "pom.template.xml", "pom.xml" into project.projectDir } -parsePom.inputs.property('projectVersion', project.version) -parsePom.inputs.property('karafVersion', libraryVersions.karaf) +parsePom.inputs.property("projectVersion", project.version) +parsePom.inputs.property("karafVersion", libraryVersions.karaf) + +/* +Now this is tricky. We need to build a custom distribution of karaf with a few features: +- included ids feature +- a bunch of configuration files in etc +Since gradle still has no karaf-assembly plugin we need to do this using maven (meh!) +*/ task assembleKaraf(type: CrossPlatformExec) { commandLine "./mvnw", "--no-transfer-progress", "clean", "package" } @@ -59,4 +64,35 @@ rootProject.subprojects.findAll() { } } -integrationTest.dependsOn(jar) \ No newline at end of file +// The PaxExam config of KarafTestSupport requires the maven dependency meta information generated here +task makeMavenDependencies { + File outputFileDir = project.file("build/classes/java/test/META-INF/maven/") + File outputFile = new File(outputFileDir, "dependencies.properties") + outputs.file(outputFile) + + doFirst { + Properties properties = new Properties() + + // information of the project itself + properties.setProperty("groupId", "${project.group}") + properties.setProperty("artifactId", project.name) + properties.setProperty("version", "${project.version}") + properties.setProperty("${project.group}/${project.name}/version", "${project.version}") + + // information of all test runtime dependencies + project.configurations.testCompileClasspath.resolvedConfiguration.resolvedArtifacts.each { + final String keyBase = it.moduleVersion.id.group + "/" + it.moduleVersion.id.name + properties.setProperty("${keyBase}/scope", "compile") + properties.setProperty("${keyBase}/type", it.extension) + properties.setProperty("${keyBase}/version", it.moduleVersion.id.version) + } + + outputFileDir.mkdirs() + new FileOutputStream(outputFile).withStream { + properties.store(it, "Generated from Gradle for PaxExam integration tests") + } + } +} + +integrationTest.dependsOn(makeMavenDependencies) +integrationTest.dependsOn(assembleKaraf) \ No newline at end of file diff --git a/karaf-assembly/pom.template.xml b/karaf-assembly/pom.template.xml index cc6535102..26ec1526c 100644 --- a/karaf-assembly/pom.template.xml +++ b/karaf-assembly/pom.template.xml @@ -74,7 +74,7 @@ org.apache.maven.plugins maven-resources-plugin - 2.6 + 3.1.0 process-resources diff --git a/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java b/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java index 9be0e7d02..53df5e530 100644 --- a/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java +++ b/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java @@ -19,91 +19,75 @@ */ package de.fhg.aisec.ids.webconsole.api; -import de.fhg.aisec.ids.api.acme.AcmeClient; import de.fhg.aisec.ids.api.conm.ConnectionManager; import de.fhg.aisec.ids.api.settings.ConnectorConfig; import de.fhg.aisec.ids.api.settings.Settings; -import org.apache.karaf.features.BootFinished; -import org.apache.karaf.features.FeaturesService; -import org.junit.Ignore; +import org.apache.karaf.itests.KarafTestSupport; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.ProbeBuilder; -import org.ops4j.pax.exam.TestProbeBuilder; import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.options.MavenUrlReference; +import org.ops4j.pax.exam.karaf.options.KarafDistributionBaseConfigurationOption; +import org.ops4j.pax.exam.karaf.options.KarafDistributionOption; +import org.ops4j.pax.exam.karaf.options.LogLevelOption; +import org.ops4j.pax.exam.options.MavenArtifactUrlReference; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerSuite; +import org.ops4j.pax.exam.spi.reactors.PerClass; import org.ops4j.pax.exam.util.Filter; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; import javax.inject.Inject; import java.io.File; import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.LinkedList; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; -import static org.ops4j.pax.exam.CoreOptions.junitBundles; -import static org.ops4j.pax.exam.CoreOptions.maven; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*; -@Ignore("Broken with Java 11, Pax Exam complains that container doesn't come up although it has been tested OK.") @RunWith(PaxExam.class) -@ExamReactorStrategy(PerSuite.class) -public class AssemblyTestIT { - - @Inject protected BundleContext bundleContext; - @Inject protected FeaturesService featuresService; - @Inject protected BootFinished bootFinished; - - @Inject - @Filter(timeout = 30000) - private ConnectionManager conm; +@ExamReactorStrategy(PerClass.class) +public class AssemblyTestIT extends KarafTestSupport { @Inject @Filter(timeout = 30000) - private AcmeClient acme; + private ConnectionManager connectionManager; @Inject @Filter(timeout = 30000) private Settings settings; - @ProbeBuilder - public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) { - probe.setHeader( - Constants.DYNAMICIMPORT_PACKAGE, "*,org.apache.felix.service.*;status=provisional"); - return probe; + @Override + public MavenArtifactUrlReference getKarafDistribution() { + return new MavenArtifactUrlReference() { + @Override + public String getURL() { + try { + return new File("build/karaf-assembly-" + System.getProperty("project.version") + ".tar.gz") + .toURI().toURL().toString(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }; } @Configuration - public Option[] config() throws MalformedURLException { - MavenUrlReference camelRepo = - maven() - .groupId("org.apache.camel.karaf") - .artifactId("apache-camel") - .classifier("features") - .type("xml") - .version("2.21.2"); - MavenUrlReference idsRepo = - maven() - .groupId("de.fhg.aisec.ids") - .artifactId("karaf-features-ids") - .classifier("features") - .type("xml") - .version(System.getProperty("project.version")); - File f = new File("build/karaf-assembly-" + System.getProperty("project.version") + ".tar.gz"); - return new Option[] { - karafDistributionConfiguration() - .frameworkUrl(f.toURI().toURL().toString()) - .unpackDirectory(new File("build/exam")) - .useDeployFolder(false), - keepRuntimeFolder(), - features(idsRepo, "ids"), - junitBundles() - }; + public Option[] config() { + final var options = new LinkedList<>(Arrays.asList(super.config())); + // Modify distribution config + ((KarafDistributionBaseConfigurationOption) options.get(0)) + .unpackDirectory(new File("build/exam")) + .useDeployFolder(false); + // Fix log level + options.replaceAll(o -> { + if (o instanceof LogLevelOption) { + return KarafDistributionOption.logLevel(LogLevelOption.LogLevel.TRACE); + } else { + return o; + } + }); + return options.toArray(new Option[0]); } @Test @@ -121,8 +105,8 @@ public void testSettings() { @Test public void testConnectionManager() { - assertNotNull(conm.listAvailableEndpoints()); - assertNotNull(conm.listIncomingConnections()); - assertNotNull(conm.listOutgoingConnections()); + assertNotNull(connectionManager.listAvailableEndpoints()); + assertNotNull(connectionManager.listIncomingConnections()); + assertNotNull(connectionManager.listOutgoingConnections()); } } diff --git a/libraryVersions.yaml b/libraryVersions.yaml index c5773e8c6..d4a047f1c 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -85,5 +85,9 @@ wsRsApi: "2.1" auth0Jwt: "3.8.2" swagger: "1.5.18" -# For OSGi integration tests -paxExam: "4.13.1" \ No newline at end of file +# Required for PaxExam integration tests +paxExam: "4.13.3" +# 4.x versions of awaitility are not supported because of old ServiceMix Hamcrest version +awaitility: "3.1.6" +servicemixHamcrest: "1.3_1" +javaxAnnotation: "1.3.2" From fb49b90b80ca16c357d6fd6ffb7ca4e662749a89 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 23 Apr 2020 21:06:42 +0200 Subject: [PATCH 005/237] Some logging for camel-multipart-processor --- .../ids/camel/multipart/MultiPartStringParser.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.java b/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.java index 2c724725f..acf9c4845 100644 --- a/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.java +++ b/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartStringParser.java @@ -24,6 +24,8 @@ import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.UploadContext; import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; @@ -36,6 +38,7 @@ public class MultiPartStringParser implements UploadContext { + private static final Logger LOG = LoggerFactory.getLogger(MultiPartStringParser.class); private final InputStream multipartInput; private final String boundary; private String header; @@ -55,11 +58,20 @@ public class MultiPartStringParser implements UploadContext { this.multipartInput.reset(); for (FileItem i : new FileUpload(new DiskFileItemFactory()).parseRequest(this)) { String fieldName = i.getFieldName(); + if (LOG.isTraceEnabled()) { + LOG.trace("Found multipart field with name \"{}\"", fieldName); + } if (MULTIPART_HEADER.equals(fieldName)) { header = i.getString(); + if (LOG.isDebugEnabled()) { + LOG.debug("Found header:\n{}", header); + } } else if (MULTIPART_PAYLOAD.equals(fieldName)) { payload = i.getInputStream(); payloadContentType = i.getContentType(); + if (LOG.isDebugEnabled()) { + LOG.debug("Found body with Content-Type \"{}\"", payloadContentType); + } } else { throw new IOException("Unknown multipart field name detected: " + fieldName); } From bfa942bbaf61da4a1f1f6b980adec831b5e60843 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 23 Apr 2020 21:39:02 +0200 Subject: [PATCH 006/237] Gradle 6.3, dependency cleanup --- build.gradle | 10 +++------- camel-ids/build.gradle | 3 --- camel-multipart-processor/build.gradle | 3 --- gradle/wrapper/gradle-wrapper.properties | 2 +- ids-acme/build.gradle.kts | 3 --- ids-api/build.gradle | 7 ++++--- ids-comm/build.gradle | 3 --- ids-container-manager/build.gradle | 3 --- ids-dataflow-control/build.gradle | 3 --- ids-dynamic-tls/build.gradle | 3 --- ids-endpoint-config/build.gradle | 3 --- ids-infomodel-manager/build.gradle.kts | 3 --- ids-route-manager/build.gradle | 3 --- ids-settings/build.gradle.kts | 3 --- ids-token-manager/build.gradle | 3 --- ids-webconsole/build.gradle | 5 +---- karaf-assembly/build.gradle | 10 ++++++++-- libraryVersions.yaml | 2 +- rat-repository/build.gradle | 3 --- 19 files changed, 18 insertions(+), 57 deletions(-) diff --git a/build.gradle b/build.gradle index 46d62a066..7f1892f71 100644 --- a/build.gradle +++ b/build.gradle @@ -107,6 +107,9 @@ subprojects { // BOM for pax, for jetty, etc. bom group: 'org.ops4j.pax', name: 'web', version: libraryVersions.pax + // Logging API + providedByBundle group: 'org.slf4j', name: 'slf4j-simple', version: libraryVersions.slf4j + // Needed for kotlin modules, provided at runtime via kotlin-osgi-bundle in karaf-features-ids compileOnly group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: libraryVersions.kotlin @@ -116,13 +119,6 @@ subprojects { testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb testImplementation group: 'com.sun.activation', name: 'javax.activation', version: libraryVersions.jaxActivation - - testImplementation "org.ops4j.pax.exam:pax-exam-container-karaf:${libraryVersions.paxExam}" - testImplementation "org.ops4j.pax.exam:pax-exam-junit4:${libraryVersions.paxExam}" - testImplementation "org.ops4j.pax.exam:pax-exam:${libraryVersions.paxExam}" - testImplementation "org.ops4j.pax.url:pax-url-aether:2.4.3" - testImplementation "javax.inject:javax.inject:1" - testImplementation "org.slf4j:slf4j-simple:1.7.12" } tasks.withType(KotlinCompile) { diff --git a/camel-ids/build.gradle b/camel-ids/build.gradle index d6b8d30a9..50b935622 100644 --- a/camel-ids/build.gradle +++ b/camel-ids/build.gradle @@ -19,9 +19,6 @@ dependencies { compileOnly group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium osgiCore group: 'org.osgi', name: 'org.osgi.core', version: libraryVersions.osgi diff --git a/camel-multipart-processor/build.gradle b/camel-multipart-processor/build.gradle index d43d342c7..02268a1db 100644 --- a/camel-multipart-processor/build.gradle +++ b/camel-multipart-processor/build.gradle @@ -14,9 +14,6 @@ dependencies { providedByBundle group: 'commons-fileupload', name: 'commons-fileupload', version: libraryVersions.commonsFileUpload - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - osgiCore group: 'org.apache.felix', name: 'org.apache.felix.framework', version: libraryVersions.felixFramework osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c1d54ccfd..94485e85b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m \ No newline at end of file diff --git a/ids-acme/build.gradle.kts b/ids-acme/build.gradle.kts index f562e2f74..98140f16b 100644 --- a/ids-acme/build.gradle.kts +++ b/ids-acme/build.gradle.kts @@ -6,9 +6,6 @@ dependencies { providedByBundle(project(":ids-api")) { isTransitive = false } - providedByBundle("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) - providedByBundle("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) - providedByFeature("org.eclipse.jetty", "jetty-util", libraryVersions["jetty"]) providedByFeature("org.apache.karaf.scheduler", "org.apache.karaf.scheduler.core", libraryVersions["karaf"]) diff --git a/ids-api/build.gradle b/ids-api/build.gradle index 0130b565c..e532717a0 100644 --- a/ids-api/build.gradle +++ b/ids-api/build.gradle @@ -10,6 +10,10 @@ protobuf { clean { delete protobuf.generatedFilesBaseDir } +// Sometimes required to fix an error caused by a non-existing folder +clean.doLast { + mkdir("${project.buildDir}/classes/kotlin/main") +} idea { module { @@ -19,9 +23,6 @@ idea { } dependencies { - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - providedByBundle group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf providedByBundle group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: libraryVersions.jackson diff --git a/ids-comm/build.gradle b/ids-comm/build.gradle index fc9afa8b9..20d3a4e61 100644 --- a/ids-comm/build.gradle +++ b/ids-comm/build.gradle @@ -8,9 +8,6 @@ dependencies { exclude group: 'net.java.dev.jna', module: 'jna' } - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - providedByBundle group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf publishCompile group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual diff --git a/ids-container-manager/build.gradle b/ids-container-manager/build.gradle index 7b9c925d9..af8f3ca97 100644 --- a/ids-container-manager/build.gradle +++ b/ids-container-manager/build.gradle @@ -19,9 +19,6 @@ idea { dependencies { providedByBundle(project(':ids-api')) { transitive = false } - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - // Provided dependency of docker-java-api providedByBundle group: 'org.glassfish', name: 'javax.json', version: libraryVersions.javaxJson // Required until our library PR has been accepted diff --git a/ids-dataflow-control/build.gradle b/ids-dataflow-control/build.gradle index e9dd0e39d..e8469a53c 100644 --- a/ids-dataflow-control/build.gradle +++ b/ids-dataflow-control/build.gradle @@ -4,9 +4,6 @@ dependencies { providedByBundle(group: 'com.google.guava', name: 'guava', version: libraryVersions.guava) { transitive = false // Avoid pulling in of checker framework and other annotation stuff } - - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j providedByBundle group: 'it.unibo.alice.tuprolog', name: 'tuprolog', version: libraryVersions.tuprolog diff --git a/ids-dynamic-tls/build.gradle b/ids-dynamic-tls/build.gradle index 6adc3de61..93e35455b 100644 --- a/ids-dynamic-tls/build.gradle +++ b/ids-dynamic-tls/build.gradle @@ -1,8 +1,5 @@ dependencies { providedByBundle(project(':ids-api')) { transitive = false } - - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j osgiCore group: 'org.osgi', name: 'org.osgi.core', version: libraryVersions.osgi diff --git a/ids-endpoint-config/build.gradle b/ids-endpoint-config/build.gradle index 71739fb9e..26347138e 100644 --- a/ids-endpoint-config/build.gradle +++ b/ids-endpoint-config/build.gradle @@ -1,9 +1,6 @@ dependencies { providedByBundle(project(':ids-api')) { transitive = false } - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium testImplementation group: 'junit', name: 'junit' diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 95e0afde7..2bacaa8cb 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -18,7 +18,4 @@ dependencies { infomodelBundle("com.fasterxml.jackson.core", "jackson-databind", libraryVersions["jackson"]) osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) - - compileOnly("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) - compileOnly("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) } diff --git a/ids-route-manager/build.gradle b/ids-route-manager/build.gradle index 5a7fbf5bf..a28cbb7b9 100644 --- a/ids-route-manager/build.gradle +++ b/ids-route-manager/build.gradle @@ -9,9 +9,6 @@ dependencies { compileOnly group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - osgiCore group: 'org.apache.felix', name: 'org.apache.felix.framework', version: libraryVersions.felixFramework osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium diff --git a/ids-settings/build.gradle.kts b/ids-settings/build.gradle.kts index 84df2acdf..1861aaf39 100644 --- a/ids-settings/build.gradle.kts +++ b/ids-settings/build.gradle.kts @@ -16,8 +16,5 @@ dependencies { exclude("org.jetbrains.kotlin", "*") } - providedByBundle("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) - providedByBundle("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) - osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) } \ No newline at end of file diff --git a/ids-token-manager/build.gradle b/ids-token-manager/build.gradle index cf2834569..200d315b4 100755 --- a/ids-token-manager/build.gradle +++ b/ids-token-manager/build.gradle @@ -1,9 +1,6 @@ dependencies { providedByBundle(project(':ids-api')) { transitive = false } - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken diff --git a/ids-webconsole/build.gradle b/ids-webconsole/build.gradle index 266e65e54..7176a0f7f 100644 --- a/ids-webconsole/build.gradle +++ b/ids-webconsole/build.gradle @@ -86,13 +86,10 @@ dependencies { implementation group: 'com.auth0', name: 'java-jwt', version: libraryVersions.auth0Jwt osgiCore group: 'org.apache.felix', name: 'org.apache.felix.framework', version: libraryVersions.felixFramework osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j compileOnly group: 'io.swagger', name: 'swagger-jaxrs', version: libraryVersions.swagger - testImplementation group: 'junit', name: 'junit' + testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito testImplementation group: 'org.apache.cxf', name: 'cxf-rt-transports-local', version: libraryVersions.cxf diff --git a/karaf-assembly/build.gradle b/karaf-assembly/build.gradle index 1a668482d..32636fbd6 100644 --- a/karaf-assembly/build.gradle +++ b/karaf-assembly/build.gradle @@ -4,13 +4,18 @@ dependencies { osgiCore group: "org.apache.felix", name: "org.apache.felix.framework", version: libraryVersions.felixFramework osgiCore group: "org.osgi", name: "osgi.cmpn", version: libraryVersions.osgiCompendium + testImplementation group: "org.ops4j.pax.exam", name: "pax-exam", version: libraryVersions.paxExam + testImplementation group: "org.ops4j.pax.exam", name: "pax-exam-junit4", version: libraryVersions.paxExam + testImplementation group: "org.ops4j.pax.exam", name: "pax-exam-container-karaf", + version: libraryVersions.paxExam testImplementation group: "org.apache.karaf.itests", name: "common", version: libraryVersions.karaf testImplementation group: "org.apache.karaf", name: "apache-karaf", version: libraryVersions.karaf, ext: "pom" testImplementation group: "org.awaitility", name: "awaitility", version: libraryVersions.awaitility testImplementation group: "org.apache.servicemix.bundles", name: "org.apache.servicemix.bundles.hamcrest", version: libraryVersions.servicemixHamcrest - testImplementation group: "javax.annotation", name: "javax.annotation-api", version: libraryVersions.javaxAnnotation + testImplementation group: "javax.annotation", name: "javax.annotation-api", + version: libraryVersions.javaxAnnotation } static def getBrandingAligned(String branding, String space = "\\u0020") { @@ -95,4 +100,5 @@ task makeMavenDependencies { } integrationTest.dependsOn(makeMavenDependencies) -integrationTest.dependsOn(assembleKaraf) \ No newline at end of file +integrationTest.dependsOn(assembleKaraf) +integrationTest.outputs.upToDateWhen { false } \ No newline at end of file diff --git a/libraryVersions.yaml b/libraryVersions.yaml index d4a047f1c..dc30c6a3b 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -37,7 +37,7 @@ checkerQual: "2.5.2" guava: "27.0-jre" kotlin: "1.3.71" tuprolog: "3.3.0" -log4j: "2.6.2" +slf4j: "1.7.30" junit4: "4.12" mockito: "3.2.0" mapdb: "3.0.7" diff --git a/rat-repository/build.gradle b/rat-repository/build.gradle index 45ab1fdb3..57bdaabdd 100644 --- a/rat-repository/build.gradle +++ b/rat-repository/build.gradle @@ -8,9 +8,6 @@ dependencies { implementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb implementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb implementation group: 'com.sun.activation', name: 'javax.activation', version: libraryVersions.jaxActivation - - implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j implementation group: 'org.xerial', name: 'sqlite-jdbc', version: libraryVersions.sqliteJdbc implementation group: 'org.eclipse.jetty', name: 'jetty-server', version: libraryVersions.jetty From bc546a67ebda6940ac97b0ffd62597d25f7a134d Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 23 Apr 2020 21:49:19 +0200 Subject: [PATCH 007/237] Fixed karaf-assembly integration test package name --- .../api/AssemblyTestIT.java => assembly/AssemblyIT.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename karaf-assembly/src/test/java/de/fhg/aisec/ids/{webconsole/api/AssemblyTestIT.java => assembly/AssemblyIT.java} (97%) diff --git a/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java b/karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java similarity index 97% rename from karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java rename to karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java index 53df5e530..f4392f859 100644 --- a/karaf-assembly/src/test/java/de/fhg/aisec/ids/webconsole/api/AssemblyTestIT.java +++ b/karaf-assembly/src/test/java/de/fhg/aisec/ids/assembly/AssemblyIT.java @@ -17,7 +17,7 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.webconsole.api; +package de.fhg.aisec.ids.assembly; import de.fhg.aisec.ids.api.conm.ConnectionManager; import de.fhg.aisec.ids.api.settings.ConnectorConfig; @@ -47,7 +47,7 @@ @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) -public class AssemblyTestIT extends KarafTestSupport { +public class AssemblyIT extends KarafTestSupport { @Inject @Filter(timeout = 30000) From fba4a1864633279c82c692cd16c01da000ce9700 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Mon, 27 Apr 2020 09:34:00 +0200 Subject: [PATCH 008/237] unprotect self-information endpoint --- .../main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java index 22fb1c3de..f8b63ed53 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/SettingsApi.java @@ -99,7 +99,6 @@ public ConnectorProfile getConnectorProfile() { @Path("/selfInformation") @Produces("application/ld+json") // TODO Document ApiOperation - @AuthorizationRequired public String getSelfInformation() { InfoModel im = WebConsoleComponent.getInfoModelManager(); if (im == null) { From b6128fc044b5c030fb6e12da1b15b413ba63ff9d Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 6 May 2020 11:49:13 +0200 Subject: [PATCH 009/237] Some cleanup and preparations for Gradle Kotlin DSL --- build.gradle | 119 +++++++++--------- camel-multipart-processor/.gitignore | 5 - camel-multipart-processor/build.gradle | 23 ---- camel-multipart-processor/build.gradle.kts | 31 +++++ .../camel/multipart/MultiPartComponent.java | 3 +- ids-infomodel-manager/build.gradle.kts | 1 - 6 files changed, 91 insertions(+), 91 deletions(-) delete mode 100644 camel-multipart-processor/.gitignore delete mode 100644 camel-multipart-processor/build.gradle create mode 100644 camel-multipart-processor/build.gradle.kts diff --git a/build.gradle b/build.gradle index 7f1892f71..315587330 100644 --- a/build.gradle +++ b/build.gradle @@ -11,25 +11,25 @@ buildscript { } plugins { - id 'java' - id 'com.google.protobuf' version '0.8.10' - id 'com.moowork.node' version '1.3.1' - id 'biz.aQute.bnd' version '4.2.0' apply false - id 'com.github.lburgazzoli.karaf' version '0.5.1' - id 'org.jetbrains.kotlin.jvm' version '1.3.71' - id 'com.github.jlouns.cpe' version '0.5.0' - id 'com.benjaminsproule.swagger' version '1.0.6' - id 'com.diffplug.gradle.spotless' version '3.13.0' - id 'com.github.jk1.dependency-license-report' version '1.2' + id "java" + id "com.google.protobuf" version "0.8.10" + id "com.moowork.node" version "1.3.1" + id "biz.aQute.bnd" version "4.2.0" apply false + id "com.github.lburgazzoli.karaf" version "0.5.1" + id "org.jetbrains.kotlin.jvm" version "1.3.71" + id "com.github.jlouns.cpe" version "0.5.0" + id "com.benjaminsproule.swagger" version "1.0.6" + id "com.diffplug.gradle.spotless" version "3.13.0" + id "com.github.jk1.dependency-license-report" version "1.2" } licenseReport { - configurations = ['compile', 'providedByFeature', 'providedByBundle'] + configurations = ["compile", "providedByFeature", "providedByBundle"] } allprojects { - group = 'de.fhg.aisec.ids' - version = '3.0.2' + group = "de.fhg.aisec.ids" + version = "3.0.2" ext.libraryVersions = new Yaml().loadAs(new FileInputStream(file("${rootDir}/libraryVersions.yaml")), Map.class) @@ -67,26 +67,26 @@ allprojects { jcenter() // References IAIS repository that contains the infomodel artifacts maven { - url 'https://maven.iais.fraunhofer.de/artifactory/eis-ids-public/' + url "https://maven.iais.fraunhofer.de/artifactory/eis-ids-public/" } } } subprojects { - apply plugin: 'biz.aQute.bnd.builder' - apply plugin: 'java' - apply plugin: 'maven' - apply plugin: 'kotlin' + apply plugin: "biz.aQute.bnd.builder" + apply plugin: "java" + apply plugin: "maven" + apply plugin: "kotlin" sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 test { - exclude '**/*IT.*' + exclude "**/*IT.*" } task integrationTest(type: Test) { - include '**/*IT.*' + include "**/*IT.*" systemProperty "project.version", "$project.version" } @@ -102,23 +102,23 @@ subprojects { // define some Bill of Materials (BOM) for all subprojects dependencies { // BOM from Karaf, sets common version for OSGi libraries - bom group: 'org.apache.karaf', name: 'karaf', version: libraryVersions.karaf + bom group: "org.apache.karaf", name: "karaf", version: libraryVersions.karaf // BOM for pax, for jetty, etc. - bom group: 'org.ops4j.pax', name: 'web', version: libraryVersions.pax + bom group: "org.ops4j.pax", name: "web", version: libraryVersions.pax // Logging API - providedByBundle group: 'org.slf4j', name: 'slf4j-simple', version: libraryVersions.slf4j + providedByBundle group: "org.slf4j", name: "slf4j-simple", version: libraryVersions.slf4j // Needed for kotlin modules, provided at runtime via kotlin-osgi-bundle in karaf-features-ids - compileOnly group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: libraryVersions.kotlin + compileOnly group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: libraryVersions.kotlin // Required for successful build with JDK 11 compileOnly group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb testImplementation group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb - testImplementation group: 'com.sun.activation', name: 'javax.activation', version: libraryVersions.jaxActivation + testImplementation group: "com.sun.activation", name: "javax.activation", version: libraryVersions.jaxActivation } tasks.withType(KotlinCompile) { @@ -128,26 +128,23 @@ subprojects { } tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' -// options.compilerArgs << '-Xlint:unchecked' + options.encoding = "UTF-8" +// options.compilerArgs << "-Xlint:unchecked" // options.deprecation = true } tasks.withType(Jar) { jar { manifest { - // set the vendor - attributes 'Bundle-Vendor': 'Fraunhofer AISEC' - - // TODO: this was set in most of the bnd files. do we really need this? - attributes '-noee': true + attributes "Bundle-Vendor": "Fraunhofer AISEC" + attributes "-noee": true } } } } -configure(subprojects.findAll { it.name != 'examples' }) { - apply plugin: 'com.diffplug.gradle.spotless' +configure(subprojects.findAll { it.name != "examples" }) { + apply plugin: "com.diffplug.gradle.spotless" spotless { java { @@ -155,11 +152,11 @@ configure(subprojects.findAll { it.name != 'examples' }) { googleJavaFormat() - licenseHeader('''/*- + licenseHeader("""/*- * ========================LICENSE_START================================= - * ''' + project.name + ''' - * %% - * Copyright (C) $YEAR Fraunhofer AISEC + * """ + project.name + """ +" * %% + * Copyright (C) \$YEAR Fraunhofer AISEC * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,26 +170,26 @@ configure(subprojects.findAll { it.name != 'examples' }) { * See the License for the specific language governing permissions and * limitations under the License. * =========================LICENSE_END================================== - */''').yearSeparator(' - ') + */""").yearSeparator(" - ") } } } -configure(subprojects.findAll { it.name == 'ids-api' || it.name == 'ids-comm' }) { - apply plugin: 'maven-publish' - apply plugin: 'signing' +configure(subprojects.findAll { it.name == "ids-api" || it.name == "ids-comm" }) { + apply plugin: "maven-publish" + apply plugin: "signing" task sourcesJar(type: Jar) { from sourceSets.main.allSource - from ('src/main') { - include 'proto/**' + from ("src/main") { + include "proto/**" } - archiveClassifier = 'sources' + archiveClassifier = "sources" } task javadocJar(type: Jar) { from javadoc - archiveClassifier = 'javadoc' + archiveClassifier = "javadoc" } // Must disable gradle metadata because of infomodel SNAPSHOT dependencies @@ -207,27 +204,27 @@ configure(subprojects.findAll { it.name == 'ids-api' || it.name == 'ids-comm' }) artifact sourcesJar artifact javadocJar pom { - name = 'IDSCP Protocol Library' - description = 'Contains the WebSocket-based Industrial Data Space Communication Protocol (IDSCP)' - url = 'https://github.com/industrial-data-space/trusted-connector' + name = "IDSCP Protocol Library" + description = "Contains the WebSocket-based Industrial Data Space Communication Protocol (IDSCP)" + url = "https://github.com/industrial-data-space/trusted-connector" licenses { license { - name = 'The Apache License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + name = "The Apache License, Version 2.0" + url = "http://www.apache.org/licenses/LICENSE-2.0.txt" } } developers { developer { - name = 'Michael Lux' - email = 'michael.lux@aisec.fraunhofer.de' - organization = 'Fraunhofer AISEC' - organizationUrl = 'aisec.fraunhofer.de' + name = "Michael Lux" + email = "michael.lux@aisec.fraunhofer.de" + organization = "Fraunhofer AISEC" + organizationUrl = "aisec.fraunhofer.de" } } scm { - connection = 'scm:git:git://github.com:industrial-data-space/trusted-connector.git' - developerConnection = 'scm:git:ssh://github.com:industrial-data-space/trusted-connector.git' - url = 'https://github.com/industrial-data-space/trusted-connector' + connection = "scm:git:git://github.com:industrial-data-space/trusted-connector.git" + developerConnection = "scm:git:ssh://github.com:industrial-data-space/trusted-connector.git" + url = "https://github.com/industrial-data-space/trusted-connector" } } } @@ -237,11 +234,11 @@ configure(subprojects.findAll { it.name == 'ids-api' || it.name == 'ids-comm' }) maven { def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + url = version.endsWith("SNAPSHOT") ? snapshotsRepoUrl : releasesRepoUrl credentials { - username = project.findProperty('deployUsername') - password = project.findProperty('deployPassword') + username = project.findProperty("deployUsername") + password = project.findProperty("deployPassword") } } } diff --git a/camel-multipart-processor/.gitignore b/camel-multipart-processor/.gitignore deleted file mode 100644 index f6a4b7789..000000000 --- a/camel-multipart-processor/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -/build/ -/generated/ -/generated-sources/ -/target/ diff --git a/camel-multipart-processor/build.gradle b/camel-multipart-processor/build.gradle deleted file mode 100644 index 02268a1db..000000000 --- a/camel-multipart-processor/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -dependencies { - providedByBundle(project(':ids-api')) { transitive = false } - - // Bill of Materials (BOM) for Camel - bom group: 'org.apache.camel', name: 'camel-parent', version: libraryVersions.camel - - providedByFeature group: 'org.apache.camel', name: 'camel-core', version: libraryVersions.camel - providedByFeature group: 'org.apache.camel', name: 'camel-http4', version: libraryVersions.camelHttp4 - - compileOnly group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - - providedByBundle group: 'org.apache.httpcomponents', name: 'httpcore-osgi', version: libraryVersions.httpcore - providedByBundle group: 'org.apache.httpcomponents', name: 'httpclient-osgi', version: libraryVersions.httpclient - - providedByBundle group: 'commons-fileupload', name: 'commons-fileupload', version: libraryVersions.commonsFileUpload - - osgiCore group: 'org.apache.felix', name: 'org.apache.felix.framework', version: libraryVersions.felixFramework - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - - testImplementation group: 'junit', name: 'junit' - testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito - testImplementation group: 'org.apache.camel', name: 'camel-test', version: libraryVersions.camel -} diff --git a/camel-multipart-processor/build.gradle.kts b/camel-multipart-processor/build.gradle.kts new file mode 100644 index 000000000..490143d8f --- /dev/null +++ b/camel-multipart-processor/build.gradle.kts @@ -0,0 +1,31 @@ +import org.yaml.snakeyaml.Yaml + +dependencies { + @Suppress("UNCHECKED_CAST") val libraryVersions = + Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + + providedByBundle(project(":ids-api")) { isTransitive = false } + + implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) + implementation("de.fraunhofer.iais.eis.ids", "infomodel-serializer", libraryVersions["infomodelSerializer"]) + + // Bill of Materials (BOM) for Camel + bom("org.apache.camel", "camel-parent", libraryVersions["camel"]) + + providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) + providedByFeature("org.apache.camel", "camel-http4", libraryVersions["camelHttp4"]) + + compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) + + providedByBundle("org.apache.httpcomponents", "httpcore-osgi", libraryVersions["httpcore"]) + providedByBundle("org.apache.httpcomponents", "httpclient-osgi", libraryVersions["httpclient"]) + + providedByBundle("commons-fileupload", "commons-fileupload", libraryVersions["commonsFileUpload"]) + + osgiCore("org.apache.felix", "org.apache.felix.framework", libraryVersions["felixFramework"]) + osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + + testImplementation("junit", "junit", libraryVersions["junit4"]) + testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) + testImplementation("org.apache.camel", "camel-test", libraryVersions["camel"]) +} diff --git a/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.java b/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.java index 2b86fa67d..1f81af92d 100644 --- a/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.java +++ b/camel-multipart-processor/src/main/java/de/fhg/aisec/ids/camel/multipart/MultiPartComponent.java @@ -36,8 +36,9 @@ @Component(name = "ids-multipart-component") public class MultiPartComponent { + @SuppressWarnings("unused") @Reference(cardinality = ReferenceCardinality.MANDATORY) - private InfoModel infoModel = null; + private InfoModel infoModel; private static MultiPartComponent instance; diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 2bacaa8cb..4efb6216d 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -6,7 +6,6 @@ dependencies { infomodelBundle(project(":ids-api")) { isTransitive = false } - // MVN resolution problem workaround for infomodel until publicly released implementation("de.fraunhofer.iais.eis.ids.infomodel", "java", libraryVersions["infomodel"]) implementation("de.fraunhofer.iais.eis.ids", "infomodel-serializer", libraryVersions["infomodelSerializer"]) From 5da4b718f9cdc7c307e3a51d62722bddfbe6d624 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 20 Apr 2020 14:46:56 +0200 Subject: [PATCH 010/237] Update latest examples ZIP --- .../trusted-connector-examples_latest.zip | Bin 34535 -> 34287 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/trusted-connector-examples_latest.zip b/examples/trusted-connector-examples_latest.zip index e1d4b965691e05b2d68bf009a05ca6fd1a488d52..55b18a4353b6d41ec30f3fbad82e7cd7df0a2cb9 100644 GIT binary patch delta 1717 zcma)*T}V@57{}kukDVO&wW)Jk(>cF3_hqD^E!K*WVrftWK?G(?1*gLe(FAvPbds1C z^-xA1H<|Qxp?SP2=>w#T5FzLy3M_B*qN0eBpwynT8{f0o$unL!+xb1u|NlHY|J5=1 z*HO9dXhTx6nlKDQ2=Uexnnl4xudhAi(g=y-k*Ffj$eMVoGAh)p z&v=dv{ChC)tASBeDdv^E}eJV*}IZ9`h zz|Lqr+&646A~7mo-RDb1)^O$dsl#YFEb-#-IrU0s4ZZ{B;OrL%HtrQX$mD9Wl|njc zMntF!GiffRP&!~@^feq|%}NS|2&=(?C*USqB>KIO(;W5Yk_O ztQI!PR4^4u5jA@j5t_X>#(+kP4l+40kP!psierE`lG{ot(!t0UDPFY^;_Gep2ReMV z_Orp3fWz+V?1^6-osv9J{XRQ}$slriDJnQ^bU>%qYK`wiXTl=t)UXQ+3gG2XHoYr4 z5hWr%ze?bDhe82+U$eg>UWkr`SyXtY8uq(27$FTUL`Or+2Wyb8_-7J29|a@>54QUq-CbRwgC2WJ gcPPFbP7e!z$=xP6Kde=!V3G(?;YWsdZ^Od3zb*|EB>(^b delta 1945 zcmZ`(Yivtl7=GJsT~{KbyBt*=8`-Uw&1HNj2X{8+P*;z5Yz~Z*1ObBg|b+cJ0z%qRRjqeeM%$aXk$CY z$fOPd<cX^H0(wOrx$wVoILF^a{9HKk(Qj^J|J) z*GW1kBV&XHGF5b@D;wnT%rdhx!sW&J?glc_JhxMhiU9>E%LwB$&YPCWl{;E(EgM@c zp51a0vLj3fXXSg3!888-T;`+(2c#5i}<|Wz*?Kd W=?gg8^6`=Z;PA5)O`Q+YfBykn0l_%{ From e568f3cb7f474e8939e5eb61302c4ebd22bd2e93 Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Mon, 11 May 2020 20:51:56 +0200 Subject: [PATCH 011/237] Trying to use GitHub CI instead of Travis --- .github/workflows/build.yml | 10 ++++++++++ .travis.yml | 22 ---------------------- README.md | 2 +- build.sh | 0 4 files changed, 11 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml mode change 100644 => 100755 build.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..5608dfe30 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,10 @@ +name: build +on: [push] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Build + run: | + ./build.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 50f786039..000000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: java -jdk: - - oraclejdk11 -services: - - docker -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.m2 - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -before_install: - - wget -O protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip - - mkdir $HOME/protoc && unzip -d $HOME/protoc protoc.zip - - export PATH=$HOME/protoc/bin:$PATH - - echo $PATH - - nvm install 12 - - npm install -g yarn -install: true -script: ./gradlew --parallel clean build diff --git a/README.md b/README.md index cb1e6d0bf..f0000ff66 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.com/industrial-data-space/trusted-connector.svg?branch=develop)](https://travis-ci.org/industrial-data-space/trusted-connector) +![build](https://github.com/industrial-data-space/trusted-connector/workflows/build/badge.svg) The _Trusted Connector_ is an Apache Karaf-based platform for the Industrial Internet of Things (IIoT). It supports Docker and trust|me as containerization environments and provides the following features: diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 From d89009235391513baeec043eb4bf5b93df287047 Mon Sep 17 00:00:00 2001 From: oxisto Date: Mon, 11 May 2020 20:57:36 +0200 Subject: [PATCH 012/237] Update build.yml --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5608dfe30..222ac6b80 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,4 +7,7 @@ jobs: - uses: actions/checkout@master - name: Build run: | + mkdir -p /home/build/core-platform + mkdir -p /home/build/.gradle + mkdir -p /home/build/.m2 ./build.sh From b34a8aed1646d0d98baf0db1cf6b6ee26155b368 Mon Sep 17 00:00:00 2001 From: oxisto Date: Mon, 11 May 2020 20:58:09 +0200 Subject: [PATCH 013/237] Update build.yml --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 222ac6b80..d150cc91d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,6 @@ jobs: - uses: actions/checkout@master - name: Build run: | - mkdir -p /home/build/core-platform mkdir -p /home/build/.gradle mkdir -p /home/build/.m2 ./build.sh From f8d8ac723b36d8ff11ddda0c5689c4fb65ca6045 Mon Sep 17 00:00:00 2001 From: oxisto Date: Mon, 11 May 2020 20:59:45 +0200 Subject: [PATCH 014/237] Update build.yml --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d150cc91d..96cb0080e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,6 @@ jobs: - uses: actions/checkout@master - name: Build run: | - mkdir -p /home/build/.gradle - mkdir -p /home/build/.m2 + mkdir -p ~/.gradle + mkdir -p ~/.m2 ./build.sh From db67e2e8d50dfbef16e367c46d90d0083ef67a89 Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Mon, 11 May 2020 21:38:08 +0200 Subject: [PATCH 015/237] Added caching --- .github/workflows/build.yml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96cb0080e..59bf776dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,8 +5,19 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Build - run: | - mkdir -p ~/.gradle - mkdir -p ~/.m2 - ./build.sh + - name: Cache gradle modules + uses: actions/cache@v1 + env: + cache-name: cache-gradle-modules + with: + path: ~/.gradle + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/gradle.build') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Build + run: | + mkdir -p ~/.gradle + mkdir -p ~/.m2 + ./build.sh From f7e01127370e8a3a5a92b6140874f67948a5928c Mon Sep 17 00:00:00 2001 From: "Banse, Christian" Date: Mon, 11 May 2020 21:53:30 +0200 Subject: [PATCH 016/237] Fixed syntax --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59bf776dd..4d942d5ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,8 +16,8 @@ jobs: ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - - name: Build - run: | - mkdir -p ~/.gradle - mkdir -p ~/.m2 - ./build.sh + - name: Build + run: | + mkdir -p ~/.gradle + mkdir -p ~/.m2 + ./build.sh From e7dd5cba9286cd98e47109b493ef2afd8f034379 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 19 May 2020 09:56:43 +0200 Subject: [PATCH 017/237] Updated jquery --- .../src/main/resources/www/package.json | 2 +- .../src/main/resources/www/yarn.lock | 1580 ++++++++--------- 2 files changed, 785 insertions(+), 797 deletions(-) diff --git a/ids-webconsole/src/main/resources/www/package.json b/ids-webconsole/src/main/resources/www/package.json index d7f6d7976..5199fcc6e 100644 --- a/ids-webconsole/src/main/resources/www/package.json +++ b/ids-webconsole/src/main/resources/www/package.json @@ -22,7 +22,7 @@ "bootstrap": "^4.2.1", "core-js": "^3.6.4", "deep-equal": "^2.0.1", - "jquery": "^3.4.1", + "jquery": "^3.5.1", "material-design-lite": "^1.3.0", "ng2-ace-editor": "^0.3.9", "popper.js": "^1.16.1", diff --git a/ids-webconsole/src/main/resources/www/yarn.lock b/ids-webconsole/src/main/resources/www/yarn.lock index 340829590..4df1f4087 100644 --- a/ids-webconsole/src/main/resources/www/yarn.lock +++ b/ids-webconsole/src/main/resources/www/yarn.lock @@ -2,29 +2,29 @@ # yarn lockfile v1 -"@angular-devkit/architect@0.901.0": - version "0.901.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.901.0.tgz#c660cb76e3bd35fc294d8e8578782b83157924aa" - integrity sha512-SlqEBkPrT40zMCy5344AsUqC76pEPCaGPaAkCIvadaz2dC9vNMzQrvubCPJHViD/TumkSX1kYmLS3iYASVM9GQ== +"@angular-devkit/architect@0.901.6": + version "0.901.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.901.6.tgz#5fb113850b025bdac894d1bb306b4d2ea51f8416" + integrity sha512-0pWzn10gCZxMCrS62NlD38qE2R7l5fPfBuNylntNqvzw9L7iS1ARgqMlAKn8KLaNG6FrXONmgUWHsV987ZICIw== dependencies: - "@angular-devkit/core" "9.1.0" + "@angular-devkit/core" "9.1.6" rxjs "6.5.4" "@angular-devkit/build-angular@~0.901.0": - version "0.901.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.901.0.tgz#f3b9459b8c28f2d6d4f3f26c45e45373cc86e5a7" - integrity sha512-ftJVNlKvIomqRfr5jFVraPqlLSUJu8YyVbFv/aCsvhNpuZGkYpTOMoJDwyywdslSTH608BIoU63IAnIz9PwUdw== - dependencies: - "@angular-devkit/architect" "0.901.0" - "@angular-devkit/build-optimizer" "0.901.0" - "@angular-devkit/build-webpack" "0.901.0" - "@angular-devkit/core" "9.1.0" + version "0.901.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.901.6.tgz#034f7ba5a5adda715fcbcc35f33ff8a7c62dd4a2" + integrity sha512-jgLFKRWSZIZZVb7fiGC0SHzBFYBkDOLTw/MRta8p81o8WzLe0uxGVP4RlIj6fZxv3Vvb1NZI4HHrgt/jASaj4A== + dependencies: + "@angular-devkit/architect" "0.901.6" + "@angular-devkit/build-optimizer" "0.901.6" + "@angular-devkit/build-webpack" "0.901.6" + "@angular-devkit/core" "9.1.6" "@babel/core" "7.9.0" "@babel/generator" "7.9.3" "@babel/preset-env" "7.9.0" "@babel/template" "7.8.6" "@jsdevtools/coverage-istanbul-loader" "3.0.3" - "@ngtools/webpack" "9.1.0" + "@ngtools/webpack" "9.1.6" ajv "6.12.0" autoprefixer "9.7.4" babel-loader "8.0.6" @@ -34,6 +34,7 @@ circular-dependency-plugin "5.2.0" copy-webpack-plugin "5.1.1" core-js "3.6.4" + css-loader "3.5.1" cssnano "4.1.10" file-loader "6.0.0" find-cache-dir "3.3.1" @@ -61,12 +62,11 @@ semver "7.1.3" source-map "0.7.3" source-map-loader "0.2.4" - source-map-support "0.5.16" speed-measure-webpack-plugin "1.3.1" style-loader "1.1.3" stylus "0.54.7" stylus-loader "3.0.2" - terser "4.6.7" + terser "4.6.10" terser-webpack-plugin "2.3.5" tree-kill "1.2.2" webpack "4.42.0" @@ -75,32 +75,32 @@ webpack-merge "4.2.2" webpack-sources "1.4.3" webpack-subresource-integrity "1.4.0" - worker-plugin "4.0.2" + worker-plugin "4.0.3" -"@angular-devkit/build-optimizer@0.901.0": - version "0.901.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.901.0.tgz#6e6262294a74de9ab2e87fd05951dc080ec12f4a" - integrity sha512-Y9sz8uf2zjilhPUVYb0K9Mio6c1d5c+csuDc15CCKzELXJwyyDxilIFgn6Eu+edM0HNQGzbIwkjy4DkR9mtuTQ== +"@angular-devkit/build-optimizer@0.901.6": + version "0.901.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.901.6.tgz#2dc85c5ae61113df16566949ae3833283864bb8b" + integrity sha512-M0H9SrOq4QOYqGCIguGQDWizf+XL7whJjBtYHxI7jEjtzar3zkTFgzZ/znv49R56Zch1niH0mBgtDxCFFWqarQ== dependencies: loader-utils "2.0.0" source-map "0.7.3" tslib "1.11.1" - typescript "3.8.3" + typescript "3.6.5" webpack-sources "1.4.3" -"@angular-devkit/build-webpack@0.901.0": - version "0.901.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.901.0.tgz#884bf9343bf85af46de00db5b2a95a06a40d06fd" - integrity sha512-Oze0VzIvHnoW12C80fiNH4HBu/GWmhJPXdNA7nRkU/tBQlIKnfngf8rQ0QbgecN2qdEXQpZJsP/XclTi3zugsg== +"@angular-devkit/build-webpack@0.901.6": + version "0.901.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.901.6.tgz#62a0d8cd94c8c61b734b0a6c149c922dd8908c42" + integrity sha512-jEk850AtIFK+xbXXiloVvueXTbJOL1mANR2UBrmWk7V4Bct+gHVerdXjn9vo1Tsd8BgemUYAcqvLldCx9MSDTg== dependencies: - "@angular-devkit/architect" "0.901.0" - "@angular-devkit/core" "9.1.0" + "@angular-devkit/architect" "0.901.6" + "@angular-devkit/core" "9.1.6" rxjs "6.5.4" -"@angular-devkit/core@9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.1.0.tgz#5cc89bb5d44c6fd12a3527bae0253adb60d64b07" - integrity sha512-vHTsrB4JaVUQ95FRnKrgo79Y3F6FokImrZdrmwkQmwAThpjXeXmpUEKZS+ZSTFRgesjiIysVGOFijARP4BQ7Bg== +"@angular-devkit/core@9.1.6": + version "9.1.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.1.6.tgz#d108430a48e58bf1efd1b87aa2edb64e3b9241d1" + integrity sha512-lYXoRtsMsfyIrNAa49Hcx79FPRW6ZrWjK2yJ3avON1Q3WEHYb/DIUP+ItyOQAkNUsCVMyK4wkddsu8PsqEW6tg== dependencies: ajv "6.12.0" fast-json-stable-stringify "2.1.0" @@ -108,30 +108,30 @@ rxjs "6.5.4" source-map "0.7.3" -"@angular-devkit/schematics@9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.1.0.tgz#f453a9ff78c34a5468cc21830ac4a46089ee1a31" - integrity sha512-cb9PSvskMwWlL54fPfCcpJoyNDWAX6Wo7CzL5qpIB2cJCPLAuyfRUYYrkO77YUST+n2HvypHz0cZ5SNGMfaaBQ== +"@angular-devkit/schematics@9.1.6": + version "9.1.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.1.6.tgz#759b01ef6815fd2d7366c3f1907d5878403a816e" + integrity sha512-twS8Sxc6NG4A0n7yITugP0snIMJ2Rm6aOGkckomWjZAP1fPo8pup8EFGc5wUBAtAOM3DJBphEnskpwEWCkBaLg== dependencies: - "@angular-devkit/core" "9.1.0" + "@angular-devkit/core" "9.1.6" ora "4.0.3" rxjs "6.5.4" "@angular/animations@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.1.0.tgz#3030e290683c0e2d63fa61060d36f659511d3b2c" - integrity sha512-o7X3HM+eocoryw3VrDUtG6Wci2KwtzyBFo3KBJXjQ16X6fwdkjTG+hLb7pp2CBFBEJW4tPYEy7cSBmEfMRTqag== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.1.7.tgz#09bf7c84c234d8b6ecaa101024a3b3e69ab198cd" + integrity sha512-1wW8ndGMLDuE2LpTN2RNRz1Dt7JgVBeVmOPMgzoA7g1uuvm+jESTrGG7W3BzLzG0BE2TeXt0fY90o4iU+S2Rmg== "@angular/cli@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.1.0.tgz#07ec165d507208bb8d8d8ab73c3e14102643edff" - integrity sha512-ofum4gPE/W3fKyzuJrpdHeOS0ZL8x0eYCgsrMyUoFodSpb5LWPqeW+56NgDTpIeny+Trx3pM9dr9QTUVTJ0vYg== - dependencies: - "@angular-devkit/architect" "0.901.0" - "@angular-devkit/core" "9.1.0" - "@angular-devkit/schematics" "9.1.0" - "@schematics/angular" "9.1.0" - "@schematics/update" "0.901.0" + version "9.1.6" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.1.6.tgz#9622745d3fdf73b3045048e7df6c44f5aa8e97f5" + integrity sha512-hQnad0LQx0n+FiMRUV2RX9+L0dLsISu7uzimGLjgJVtW6Bc1cVnaTkKhOqHRQG2Q4Iv8adKWf5UL5tMZz/roDA== + dependencies: + "@angular-devkit/architect" "0.901.6" + "@angular-devkit/core" "9.1.6" + "@angular-devkit/schematics" "9.1.6" + "@schematics/angular" "9.1.6" + "@schematics/update" "0.901.6" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" debug "4.1.1" @@ -140,7 +140,7 @@ npm-package-arg "8.0.1" npm-pick-manifest "6.0.0" open "7.0.3" - pacote "11.1.4" + pacote "9.5.12" read-package-tree "5.3.1" rimraf "3.0.2" semver "7.1.3" @@ -149,14 +149,14 @@ uuid "7.0.2" "@angular/common@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.1.0.tgz#f9b5353a28f9da6c06266bc7244bbabf9e005176" - integrity sha512-6JPLNtMhI03bGTVQJeSwc+dTjV6DtP7M/BAyzIV0InZP1D6XsOh2QahLFIaaN2sSxYA2ClKuwfX1v+rx9AbXQA== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.1.7.tgz#79ebbe3c08ced0070314beb10bbccfb8927dfe62" + integrity sha512-04ef+J8bnOnjYbdRsm82IdIaaLFZ6QWh4SLtjnYhgCjEe4Stf59g+zRNPMauMFDQYDCp3foPo0djk1CPfEd8AQ== "@angular/compiler-cli@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.1.0.tgz#5887c278a2fe1f3165018b1cbceef71d9023b9ae" - integrity sha512-xZ8mVPmPporSTtvNA+cbFJQymLzuWfMX6HDDgztZ2eZ5WcQJYloRN4CcYMEzDhCxfV1Zw9Tfc2l14jZD8osi6g== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.1.7.tgz#ecd1d47b0368ed21dfcef980b3aaeb37085a3612" + integrity sha512-8HT8+UuSohrXlF90eewG2XuhtOEIfJ2UlijnSB10/+ZyroSdTKckoiFSps86nTd/EfrBblqNUMbwjOxIkzac3w== dependencies: canonical-path "1.0.0" chokidar "^3.0.0" @@ -172,42 +172,42 @@ yargs "15.3.0" "@angular/compiler@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.1.0.tgz#e55b4f2f24df75283002d5e8e85e1acfc46928f6" - integrity sha512-QHw/JSeTXHiJQ2Ih0EtU7FGsYcOr+0hwZhqwSW3EEn8TtUgA3DS5lXeiDV66f+3DdvNZFPmgiZIvun3ypxn1HA== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.1.7.tgz#e094f99f8742994761adeb1fd8090b21d2abff98" + integrity sha512-BiHJ3rAd00aJkur7ohnXjqBmz2QkSTAAFWLuBTYuHysxP4zJD54y4uUtsrCUReKL+8dkUv8AcfXBAkCBLvBUYg== "@angular/core@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.1.0.tgz#9dfc386bd1461e0fd4786031fd245da04371421c" - integrity sha512-RVlyegdIAij0P1wLY5ObIdsBAzvmHkHfElnmfiNKhaDftP6U/3zRtaKDu0bq0jvn1WCQ8zXxFQ8AWyKZwyFS+w== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.1.7.tgz#0465c26d9101389602e3ff9e502f83f3655e9fe1" + integrity sha512-uJSZ+rdGL47gc3A+Fal1XwJYB4WWpYJrNifvoQ2nOs+X5Qu+j0HN6GXPJb4kixoNzjYCGxmLoirdT3xhNZFcfQ== "@angular/forms@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.1.0.tgz#de14e34aa37bd41a28f93fee8666cd7f6393078c" - integrity sha512-5GC8HQlPChPV+168zLlm4yj4syA6N9ChSKV0tmzj1zIfMcub1UAOaB9IYaXRHQsjPFh9OuQXwmkzScyAfhEVjA== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.1.7.tgz#cdefbc7c7093fd37b417975f18b875a798cbd2d9" + integrity sha512-/bRs5hSFDUjOrq2vw11HoS25oEu7KYVxPbQiEjeBHJo82yDmSO+1cVukh6ulDi7iv1sJwSzikDtE9+xDx1ocfQ== "@angular/platform-browser-dynamic@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.0.tgz#830bd5038d1875736e87e68c3aef44f0f835e418" - integrity sha512-sMtz/poQ3TYaWZzWjrn9apKUZ/WKql2MYCWbpax7pql3GgC9OoTslc7ZEe7/d3ynfFE/CQqWBBOuWGD71Z0LMQ== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.7.tgz#cf20e8f9ba3512ca906d7f21cf0926f0222a95ad" + integrity sha512-DyUDGxp4kF4majcm9COVzu/9wzmgnfj+d6GUEjYkbqSH9QP05LonJ6wHMNxNMN6qMfawdCxDe0TnNDRPmHUj9w== "@angular/platform-browser@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.1.0.tgz#0bd40db37c9e314944c149de935b0f6cdd1f7350" - integrity sha512-OsS/blUjl8ranmDaRADjFAmvnlmwbT6WNU7dVov7FhV0rqesbwaOJ5bR0LSYHYpej7Jaa6oYk0v0XWkaH9LTFg== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.1.7.tgz#47e473660c772f80245bcf872aa7e3df9e875a70" + integrity sha512-zwNCnn4Ozax80YrkFcLoQ/7bVR7jPk7+QT++Nf9MmQwsaqa0Ve1IYa6Hg9Y1Kf4wquI9TdxMN17TPKmX8iNIaA== "@angular/platform-server@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-9.1.0.tgz#a4d5b20724acd54219603e32cee88b0b58ee6617" - integrity sha512-JboTIUBgf9yHRjF93q8NJQoeIp5Zp4kg8Nmw1QLWO6SV+OpiOpKSrlScMVncCh0KiU6SIOmiuHJwBhLm78fi+Q== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-9.1.7.tgz#b6648cfd2aeb922f1df9954483f7a1538fbf396b" + integrity sha512-EapDvdLuW0HAg17FOFpwPAPAPk6/qV14rJj1gylqXfjsVNmjwxJvEkwgzXGnV28w7kJzTfm5J+jBCw5MWe80tA== dependencies: domino "^2.1.2" - xhr2 "^0.1.4" + xhr2 "^0.2.0" "@angular/router@~9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.1.0.tgz#df059c0f64fa41ada8f6b5ce741fe47d49f10194" - integrity sha512-cExO1nPnoPFiUJWZ28hTHozPLFoCmqr3xqcM57We0hhKE0esdrO+gRWKRH0EJERukLbU8coPKVhA8daGUpASiQ== + version "9.1.7" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.1.7.tgz#ce9af75cec470f69122f2217bd5bdcfac7b74201" + integrity sha512-ycrkhkCbfOMCe9PngFjnyk8nH5jt0Kyb2NPtjmaGOtSCuZBZ0kOU0rQGmQnj3d2PiT0Yir59S8eEAf3Fh0iDuw== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" @@ -216,16 +216,16 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" - integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== +"@babel/compat-data@^7.9.0", "@babel/compat-data@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.6.tgz#3f604c40e420131affe6f2c8052e9a275ae2049b" + integrity sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g== dependencies: - browserslist "^4.9.1" + browserslist "^4.11.1" invariant "^2.2.4" semver "^5.5.0" -"@babel/core@7.9.0", "@babel/core@^7.7.5": +"@babel/core@7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== @@ -247,6 +247,28 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.7.5": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.6.tgz#d9aa1f580abf3b2286ef40b6904d390904c63376" + integrity sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.6" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.6" + "@babel/parser" "^7.9.6" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.6" + "@babel/types" "^7.9.6" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/generator@7.9.3": version "7.9.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.3.tgz#7c8b2956c6f68b3ab732bd16305916fbba521d94" @@ -257,12 +279,12 @@ lodash "^4.17.13" source-map "^0.5.0" -"@babel/generator@^7.9.0": - version "7.9.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" - integrity sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA== +"@babel/generator@^7.9.0", "@babel/generator@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.6.tgz#5408c82ac5de98cda0d77d8124e99fa1f2170a43" + integrity sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ== dependencies: - "@babel/types" "^7.9.0" + "@babel/types" "^7.9.6" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -283,12 +305,12 @@ "@babel/types" "^7.8.3" "@babel/helper-compilation-targets@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" - integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz#1e05b7ccc9d38d2f8b40b458b380a04dcfadd38a" + integrity sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw== dependencies: - "@babel/compat-data" "^7.8.6" - browserslist "^4.9.1" + "@babel/compat-data" "^7.9.6" + browserslist "^4.11.1" invariant "^2.2.4" levenary "^1.1.1" semver "^5.5.0" @@ -319,14 +341,14 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== +"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== dependencies: "@babel/helper-get-function-arity" "^7.8.3" "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/types" "^7.9.5" "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" @@ -400,14 +422,14 @@ "@babel/types" "^7.8.3" "@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" - integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz#03149d7e6a5586ab6764996cd31d6981a17e1444" + integrity sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA== dependencies: "@babel/helper-member-expression-to-functions" "^7.8.3" "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/traverse" "^7.8.6" - "@babel/types" "^7.8.6" + "@babel/traverse" "^7.9.6" + "@babel/types" "^7.9.6" "@babel/helper-simple-access@^7.8.3": version "7.8.3" @@ -424,10 +446,10 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-validator-identifier@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" - integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== "@babel/helper-wrap-function@^7.8.3": version "7.8.3" @@ -439,14 +461,14 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helpers@^7.9.0": - version "7.9.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" - integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== +"@babel/helpers@^7.9.0", "@babel/helpers@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.6.tgz#092c774743471d0bb6c7de3ad465ab3d3486d580" + integrity sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.9.0" - "@babel/types" "^7.9.0" + "@babel/traverse" "^7.9.6" + "@babel/types" "^7.9.6" "@babel/highlight@^7.8.3": version "7.9.0" @@ -457,10 +479,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": - version "7.9.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" - integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== +"@babel/parser@^7.8.6", "@babel/parser@^7.9.0", "@babel/parser@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.6.tgz#3b1bbb30dabe600cd72db58720998376ff653bc7" + integrity sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q== "@babel/plugin-proposal-async-generator-functions@^7.8.3": version "7.8.3" @@ -504,12 +526,13 @@ "@babel/plugin-syntax-numeric-separator" "^7.8.3" "@babel/plugin-proposal-object-rest-spread@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f" - integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz#7a093586fcb18b08266eb1a7177da671ac575b63" + integrity sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A== dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.9.5" "@babel/plugin-proposal-optional-catch-binding@^7.8.3": version "7.8.3" @@ -630,13 +653,13 @@ lodash "^4.17.13" "@babel/plugin-transform-classes@^7.9.0": - version "7.9.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d" - integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ== + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c" + integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg== dependencies: "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-define-map" "^7.8.3" - "@babel/helper-function-name" "^7.8.3" + "@babel/helper-function-name" "^7.9.5" "@babel/helper-optimise-call-expression" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-replace-supers" "^7.8.6" @@ -651,9 +674,9 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-destructuring@^7.8.3": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz#fadb2bc8e90ccaf5658de6f8d4d22ff6272a2f4b" - integrity sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ== + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz#72c97cf5f38604aea3abf3b935b0e17b1db76a50" + integrity sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q== dependencies: "@babel/helper-plugin-utils" "^7.8.3" @@ -710,33 +733,33 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-modules-amd@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" - integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz#8539ec42c153d12ea3836e0e3ac30d5aae7b258e" + integrity sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw== dependencies: "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" + babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-commonjs@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" - integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz#64b7474a4279ee588cacd1906695ca721687c277" + integrity sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ== dependencies: "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-simple-access" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" + babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" - integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz#207f1461c78a231d5337a92140e52422510d81a4" + integrity sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg== dependencies: "@babel/helper-hoist-variables" "^7.8.3" "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" + babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-umd@^7.9.0": version "7.9.0" @@ -768,10 +791,10 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-replace-supers" "^7.8.3" -"@babel/plugin-transform-parameters@^7.8.7": - version "7.9.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz#3028d0cc20ddc733166c6e9c8534559cee09f54a" - integrity sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg== +"@babel/plugin-transform-parameters@^7.8.7", "@babel/plugin-transform-parameters@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz#173b265746f5e15b2afe527eeda65b73623a0795" + integrity sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA== dependencies: "@babel/helper-get-function-arity" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" @@ -920,13 +943,13 @@ esutils "^2.0.2" "@babel/runtime@^7.8.4": - version "7.9.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" - integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f" + integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@7.8.6", "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": +"@babel/template@7.8.6", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== @@ -935,27 +958,27 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" - integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== +"@babel/traverse@^7.8.3", "@babel/traverse@^7.9.0", "@babel/traverse@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.6.tgz#5540d7577697bf619cc57b92aa0f1c231a94f442" + integrity sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.9.0" - "@babel/helper-function-name" "^7.8.3" + "@babel/generator" "^7.9.6" + "@babel/helper-function-name" "^7.9.5" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.9.0" - "@babel/types" "^7.9.0" + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" - integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== +"@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5", "@babel/types@^7.9.6": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7" + integrity sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA== dependencies: - "@babel/helper-validator-identifier" "^7.9.0" + "@babel/helper-validator-identifier" "^7.9.5" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -975,84 +998,44 @@ merge-source-map "^1.1.0" schema-utils "^2.6.4" -"@ngtools/webpack@9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.1.0.tgz#c082d9e64e5900189e4612f657d68e5b81ae277c" - integrity sha512-kQ+1N/F+5tuUXiiaoqJwhcOIM0I93EEvF3xwpTLRm91wl2i8R1261LvsD/uQPrgLrZNGR6eFhFF1Izn2PnIjQA== +"@ngtools/webpack@9.1.6": + version "9.1.6" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.1.6.tgz#7fa8763d4e128a4e371bafa9328a64cf1de246dd" + integrity sha512-W/9kENoiYARDGXqXSmOekQddUlQUVxfYP7JgQwqdg7JYktIpThicbV/iLBChZwWnmn9mb7MDw1IPeUTkZzrO2Q== dependencies: - "@angular-devkit/core" "9.1.0" + "@angular-devkit/core" "9.1.6" enhanced-resolve "4.1.1" rxjs "6.5.4" webpack-sources "1.4.3" -"@npmcli/ci-detect@^1.0.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.2.0.tgz#0df142a1ac3bba6cbf2e9da1a6994cd898e32c95" - integrity sha512-JtktVH7ASBVIWsQTFlFpeOzhBJskvoBCTfeeRhhZy7ybATcUvwiwotZ8j5rkqUUyB69lIy/AvboiiiGBjYBKBA== - -"@npmcli/git@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.1.tgz#d7ecaa9c945de6bb1af5a7e6ea634771193c168b" - integrity sha512-hVatexiBtx71F01Ars38Hr5AFUGmJgHAfQtRlO5fJlnAawRGSXwEFgjB5i3XdUUmElZU/RXy7fefN02dZKxgPw== - dependencies: - "@npmcli/promise-spawn" "^1.1.0" - mkdirp "^1.0.3" - npm-pick-manifest "^6.0.0" - promise-inflight "^1.0.1" - promise-retry "^1.1.1" - unique-filename "^1.1.1" - which "^2.0.2" - -"@npmcli/installed-package-contents@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.5.tgz#cc78565e55d9f14d46acf46a96f70934e516fa3d" - integrity sha512-aKIwguaaqb6ViwSOFytniGvLPb9SMCUm39TgM3SfUo7n0TxUMbwoXfpwyvQ4blm10lzbAwTsvjr7QZ85LvTi4A== - dependencies: - npm-bundled "^1.1.1" - npm-normalize-package-bin "^1.0.1" - read-package-json-fast "^1.1.1" - readdir-scoped-modules "^1.1.0" - -"@npmcli/promise-spawn@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.1.0.tgz#660009a5c54209142ec7c469c190d212834b6087" - integrity sha512-FwbuYN9KXBkloLeIR3xRgI8dyOdfK/KzaJlChszNuwmUXD1lHXfLlSeo4n4KrKt2udIK9K9/TzlnyCA3ubM2fA== - dependencies: - infer-owner "^1.0.4" - "@saritasa/tslint-config-angular@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@saritasa/tslint-config-angular/-/tslint-config-angular-2.0.0.tgz#9e76c98081b1bc54c260e1c27abd5cd4ef8d2525" integrity sha512-zs7nOOgxOA3WpNeRLS2Qcuu0BHU/GN/n9Kfbv//w0fzZinxeZKMaLOOnDcSlq4JGgOp6AbVJeCR8l50enwEasQ== -"@schematics/angular@9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.1.0.tgz#fc0ad9099d3c3be3044d6b3f260cac6eb9f3e564" - integrity sha512-qkehaITQ1S1udfnnBY5CXGWnk1iVFI8cZayjLUlRfD5w+6v9if3VIuqPssX96MqvkbjyRu1N214+ieaawzLmuA== +"@schematics/angular@9.1.6": + version "9.1.6" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.1.6.tgz#411b45174b3900dc79d061a86aec8539894dd06b" + integrity sha512-Q9lPTf1/pXBWuFOLzwtrU88Gwkfn9JLiSb45xSQZ771cCD68tZyL4V9fH+u7139y3H3ID2xebMs7WiddAERLyw== dependencies: - "@angular-devkit/core" "9.1.0" - "@angular-devkit/schematics" "9.1.0" + "@angular-devkit/core" "9.1.6" + "@angular-devkit/schematics" "9.1.6" -"@schematics/update@0.901.0": - version "0.901.0" - resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.901.0.tgz#3e08231354f2c414c7d5b3bde1d9f7c08c664a74" - integrity sha512-u2VESL1dgOSGZK/wcWEz0WcCU/yv764zhzCQerCwUtbV1CISSSDZ6x+prVYDXOdxWBGtDos2MbCF3GEJJI1T+w== +"@schematics/update@0.901.6": + version "0.901.6" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.901.6.tgz#a6bf0ec294983373ec8e9d675d50e8b44c6a7bc7" + integrity sha512-fKDjD/nGOsrPglOeMVNW+/wa8t73XBrsVneaLg3qmWp6c80JQAxwryE+3MTnBP7apZCLR2YZlKySbY54gLRs6w== dependencies: - "@angular-devkit/core" "9.1.0" - "@angular-devkit/schematics" "9.1.0" + "@angular-devkit/core" "9.1.6" + "@angular-devkit/schematics" "9.1.6" "@yarnpkg/lockfile" "1.1.0" ini "1.3.5" npm-package-arg "^8.0.0" - pacote "11.1.4" + pacote "9.5.12" rxjs "6.5.4" semver "7.1.3" semver-intersect "1.4.0" -"@tootallnate/once@1": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.0.0.tgz#9c13c2574c92d4503b005feca8f2e16cc1611506" - integrity sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA== - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -1078,19 +1061,19 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "13.9.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.8.tgz#09976420fc80a7a00bf40680c63815ed8c7616f4" - integrity sha512-1WgO8hsyHynlx7nhP1kr0OFzsgKz5XDQL+Lfc3b1Q3qIln/n8cKD4m09NJ0+P1Rq7Zgnc7N0+SsMnoD1rEb0kA== + version "14.0.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.1.tgz#5d93e0a099cd0acd5ef3d5bde3c086e1f49ff68c" + integrity sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA== "@types/node@^12.11.1": - version "12.12.34" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.34.tgz#0a5d6ae5d22612f0cf5f10320e1fc5d2a745dcb8" - integrity sha512-BneGN0J9ke24lBRn44hVHNeDlrXRYF+VRp0HbSUNnEZahXGAysHZIqnf/hER6aabdBgzM4YOV4jrR8gj4Zfi0g== + version "12.12.39" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.39.tgz#532d25c1e639d89dd6f3aa1d7b3962e3e7fa943d" + integrity sha512-pADGfwnDkr6zagDwEiCVE4yQrv7XDkoeVa4OfA9Ju/zRTk6YNDLGtQbkdL4/56mCQQCs4AhNrBIag6jrp7ZuOg== "@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" + integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== "@types/source-list-map@*": version "0.1.2" @@ -1098,9 +1081,9 @@ integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/vis@^4.21.9": - version "4.21.19" - resolved "https://registry.yarnpkg.com/@types/vis/-/vis-4.21.19.tgz#e1ad964deed4d1a5499312410e2ce19693378a78" - integrity sha512-SzD6R7pg3TcpzIj+F++ez83WuWhOZ+D05LCbjCaVR41NbMpS6xAdc8lActRK3Cwd9cv5LmoCeN5SAsvXIeAseg== + version "4.21.20" + resolved "https://registry.yarnpkg.com/@types/vis/-/vis-4.21.20.tgz#b2153ac61dd7fda481857025ca1ef1556038ef11" + integrity sha512-3bejsXnnszmUq6bX55QkkoqkulWJcJ7Z/RgjsUFT1HsWIa1EGmsX/bl3DCyCXnKcxwciOjYvH4szY9KA1miNXw== dependencies: moment ">=2.13.0" @@ -1274,10 +1257,13 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +JSONStream@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" @@ -1288,29 +1274,34 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: negotiator "0.6.2" ace-builds@^1.4.2: - version "1.4.9" - resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.9.tgz#2b9b020706871f30e97f5510af891149f144d3d8" - integrity sha512-6I+uUDsj9AKu45VgJvloplr2DtGXRxsXNfdV9TypDkDi9MBiIV+oRNFJAf0g1b42Er3fgaVzMbLBxCeJQYNtSA== + version "1.4.11" + resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.11.tgz#b1f19a891afcef1d26522473082baf80067e855f" + integrity sha512-keACH1d7MvAh72fE/us36WQzOFQPJbHphNpj33pXwVZOM84pTWcdFzIAvngxOGIGLTm7gtUP2eJ4Ku6VaPo8bw== acorn@^6.2.1: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== -agent-base@6: - version "6.0.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" - integrity sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw== +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: - debug "4" + es6-promisify "^5.0.0" -agentkeepalive@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.0.tgz#a48e040ed16745dd29ce923675f60c9c90f39ee0" - integrity sha512-CW/n1wxF8RpEuuiq6Vbn9S8m0VSYDMnZESqaJ6F2cWN9fY8rei2qaxweIaRgq+ek8TqfoFIsUjaGNKGGEHElSg== +agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== dependencies: - debug "^4.1.0" - depd "^1.1.2" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -1331,7 +1322,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@6.12.0, ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: +ajv@6.12.0: version "6.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== @@ -1341,6 +1332,16 @@ ajv@6.12.0, ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -1419,19 +1420,11 @@ app-root-path@^2.2.1: resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== -aproba@^1.0.3, aproba@^1.1.1: +aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1578,7 +1571,7 @@ autoprefixer@9.7.4: postcss "^7.0.26" postcss-value-parser "^4.0.2" -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.1: +available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== @@ -1612,10 +1605,10 @@ babel-loader@8.0.6: mkdirp "^0.5.1" pify "^4.0.1" -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" @@ -1676,16 +1669,21 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bluebird@^3.5.5: +bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +bn.js@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.1.tgz#48efc4031a9c4041b9c99c6941d903463ab62eb5" + integrity sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA== + body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -1720,9 +1718,9 @@ boolbase@^1.0.0, boolbase@~1.0.0: integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= bootstrap@^4.2.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01" - integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA== + version "4.5.0" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.0.tgz#97d9dbcb5a8972f8722c9962483543b907d9b9ec" + integrity sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA== brace-expansion@^1.1.7: version "1.1.11" @@ -1796,7 +1794,7 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0: +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= @@ -1805,17 +1803,19 @@ browserify-rsa@^4.0.0: randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" + version "4.2.0" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.0.tgz#545d0b1b07e6b2c99211082bf1b12cce7a0b0e11" + integrity sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.2" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" browserify-zlib@^0.2.0: version "0.2.0" @@ -1824,13 +1824,13 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.8.3, browserslist@^4.9.1: - version "4.11.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" - integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== +browserslist@^4.0.0, browserslist@^4.11.1, browserslist@^4.8.3, browserslist@^4.8.5, browserslist@^4.9.1: + version "4.12.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" + integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== dependencies: - caniuse-lite "^1.0.30001038" - electron-to-chromium "^1.3.390" + caniuse-lite "^1.0.30001043" + electron-to-chromium "^1.3.413" node-releases "^1.1.53" pkg-up "^2.0.0" @@ -1883,7 +1883,7 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cacache@15.0.0, cacache@^15.0.0: +cacache@15.0.0: version "15.0.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.0.tgz#133b59edbd2a37ea8ef2d54964c6f247e47e5059" integrity sha512-L0JpXHhplbJSiDGzyJJnJCTL7er7NzbBgxzVqLswEb4bO91Zbv17OUMuUeu/q0ZwKn3V+1HM4wb9tO4eVE/K8g== @@ -1906,7 +1906,7 @@ cacache@15.0.0, cacache@^15.0.0: tar "^6.0.1" unique-filename "^1.1.1" -cacache@^12.0.2, cacache@^12.0.3: +cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== @@ -1985,7 +1985,7 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== @@ -2000,10 +2000,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001038: - version "1.0.30001038" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz#44da3cbca2ab6cb6aa83d1be5d324e17f141caff" - integrity sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001043: + version "1.0.30001062" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001062.tgz#d814b648338504b315222ace6f1a533d9a55e390" + integrity sha512-ei9ZqeOnN7edDrb24QfJ0OZicpEbsWxv7WusOiQGz/f2SfvBgHHbOEwBJ8HKGVSyx8Z6ndPjxzR6m0NQq+0bfw== canonical-path@1.0.0: version "1.0.0" @@ -2037,10 +2037,10 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" - integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8" + integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -2048,7 +2048,7 @@ chardet@^0.7.0: is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.3.0" + readdirp "~3.4.0" optionalDependencies: fsevents "~2.1.2" @@ -2071,11 +2071,16 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3, chownr@^1.1.4: +chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -2119,14 +2124,14 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" - integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.3.0.tgz#0632239a4b5aa4c958610142c34bb7a651fc8df5" + integrity sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w== cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== cliui@^4.0.0: version "4.1.0" @@ -2309,11 +2314,6 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -2384,18 +2384,23 @@ copy-webpack-plugin@5.1.1: webpack-log "^2.0.0" core-js-compat@^3.6.2: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" - integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA== + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== dependencies: - browserslist "^4.8.3" + browserslist "^4.8.5" semver "7.0.0" -core-js@3.6.4, core-js@^3.6.4: +core-js@3.6.4: version "3.6.4" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== +core-js@^3.6.4: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2419,7 +2424,7 @@ create-ecdh@^4.0.0: bn.js "^4.1.0" elliptic "^6.0.0" -create-hash@^1.1.0, create-hash@^1.1.2: +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== @@ -2430,7 +2435,7 @@ create-hash@^1.1.0, create-hash@^1.1.2: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -2483,6 +2488,25 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-loader@3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.1.tgz#db2b2336f4169edb68e6a829ad4fd36552647b77" + integrity sha512-0G4CbcZzQ9D1Q6ndOfjFuMDo8uLYMu5vc9Abs5ztyHcKvmil6GJrMiNjzzi3tQvUF+mVRuDg7bE6Oc0Prolgig== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.27" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.0.3" + schema-utils "^2.6.5" + semver "^6.3.0" + css-parse@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" @@ -2656,27 +2680,27 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@4, debug@4.1.1, debug@^4.1.0, debug@^4.1.1: +debug@3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4.1.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" -debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: +debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" -debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -2705,9 +2729,9 @@ deep-equal@^1.0.1: regexp.prototype.flags "^1.2.0" deep-equal@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.2.tgz#e68291e245493ae908ca7190c1deea57a01ed82b" - integrity sha512-kX0bjV7tdMuhrhzKPEnVwqfQCuf+IEfN+4Xqv4eKd75xGRyn8yzdQ9ujPY6a221rgJKyQC4KBu1PibDTpa6m9w== + version "2.0.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.3.tgz#cad1c15277ad78a5c01c49c2dee0f54de8a6a7b0" + integrity sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA== dependencies: es-abstract "^1.17.5" es-get-iterator "^1.1.0" @@ -2715,18 +2739,14 @@ deep-equal@^2.0.1: is-date-object "^1.0.2" is-regex "^1.0.5" isarray "^2.0.5" - object-is "^1.0.2" + object-is "^1.1.2" object-keys "^1.1.1" + object.assign "^4.1.0" regexp.prototype.flags "^1.3.0" side-channel "^1.0.2" which-boxed-primitive "^1.0.1" which-collection "^1.0.1" - which-typed-array "^1.1.1" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + which-typed-array "^1.1.2" default-gateway@^4.2.0: version "4.2.0" @@ -2790,12 +2810,7 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -depd@^1.1.2, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= @@ -2818,11 +2833,6 @@ destroy@~1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - detect-node@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" @@ -2901,9 +2911,9 @@ domelementtype@^2.0.1: integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== domino@^2.1.2: - version "2.1.4" - resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.4.tgz#78922e7fab7c610f35792b6c745b7962d342e9c4" - integrity sha512-l70mlQ7IjPKC8kT7GljQXJZmt5OqFL+RE91ik5y5WWQtsd9wP8R7gpFnNu96fK5MqAAZRXfLLsnzKtkty5fWGQ== + version "2.1.5" + resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.5.tgz#4aa08e395d496c463c3afee1cd0f7173f63eacb5" + integrity sha512-vMDo7f6ogUV9PkzmxXLiXzJkJZqU09Le4C40mj+HmAGS/2FPmdetoNOQZXpu2kekn0GJKvtwKMAVoruTj60Xww== domutils@^1.7.0: version "1.7.0" @@ -2943,12 +2953,12 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.390: - version "1.3.392" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz#280ab4f7a3ae47419cfabb15dbfc1567be7f1111" - integrity sha512-/hsgeVdReDsyTBE0aU9FRdh1wnNPrX3xlz3t61F+CJPOT+Umfi9DXHsCX85TEgWZQqlow0Rw44/4/jbU2Sqgkg== +electron-to-chromium@^1.3.413: + version "1.3.443" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.443.tgz#b01c8933e820a728afc5dde7dd535c53ff55ab11" + integrity sha512-ty0LEroTap/xfMy31oQ3XX+Q377QvWvJaha2cmuXcbmBiX2EIB5SNDQ0hp8lhvxj63WG0zOgm/4MQ/oUBdfQqg== -elliptic@^6.0.0: +elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== @@ -2981,7 +2991,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: +encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= @@ -3005,9 +3015,9 @@ enhanced-resolve@4.1.1, enhanced-resolve@^4.1.0: tapable "^1.0.0" entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.2.tgz#ac74db0bba8d33808bbf36809c3a5c3683531436" + integrity sha512-dmD3AvJQBUjKpcNkoqr+x+IF0SdRtPz9Vk0uTy4yWqga9ibB6s4v++QFWNohjiUGoMlF552ZvNyXDxz5iW0qmw== err-code@^1.0.0: version "1.1.2" @@ -3067,6 +3077,18 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3113,9 +3135,9 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== events@^3.0.0: version "3.1.0" @@ -3281,7 +3303,7 @@ faye-websocket@~0.11.1: dependencies: websocket-driver ">=0.5.1" -figgy-pudding@^3.5.1: +figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== @@ -3456,7 +3478,7 @@ fs-minipass@^1.2.5: dependencies: minipass "^2.6.0" -fs-minipass@^2.0.0, fs-minipass@^2.1.0: +fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -3479,36 +3501,27 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.12" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" - integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: bindings "^1.5.0" nan "^2.12.1" fsevents@~2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== gensync@^1.0.0-beta.1: version "1.0.0-beta.1" @@ -3525,7 +3538,7 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-stream@^4.0.0: +get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -3559,7 +3572,7 @@ glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@7.1.6, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@7.1.6, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3600,9 +3613,9 @@ globby@^7.1.1: slash "^1.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== hammerjs@^2.0.8: version "2.0.8" @@ -3642,11 +3655,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -3686,12 +3694,13 @@ has@^1.0.0, has@^1.0.3: function-bind "^1.1.1" hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" @@ -3715,7 +3724,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hosted-git-info@^2.1.4: +hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== @@ -3753,14 +3762,14 @@ html-comment-regex@^1.1.0: integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== html-entities@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== -http-cache-semantics@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== http-deceiver@^1.2.7: version "1.2.7" @@ -3804,14 +3813,13 @@ http-errors@~1.7.2: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" + agent-base "4" + debug "3.1.0" http-proxy-middleware@0.19.1: version "0.19.1" @@ -3824,9 +3832,9 @@ http-proxy-middleware@0.19.1: micromatch "^3.1.10" http-proxy@^1.17.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" - integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: eventemitter3 "^4.0.0" follow-redirects "^1.0.0" @@ -3846,13 +3854,13 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== +https-proxy-agent@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== dependencies: - agent-base "6" - debug "4" + agent-base "^4.3.0" + debug "^3.1.0" humanize-ms@^1.2.1: version "1.2.1" @@ -3861,13 +3869,20 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -3878,7 +3893,7 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore-walk@^3.0.1, ignore-walk@^3.0.3: +ignore-walk@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== @@ -3953,7 +3968,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3968,7 +3983,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@1.3.5, ini@~1.3.0: +ini@1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -4212,11 +4227,6 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= - is-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" @@ -4275,11 +4285,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - is-regex@^1.0.4, is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" @@ -4357,9 +4362,11 @@ is-wsl@^1.1.0: integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= is-wsl@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" - integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" @@ -4399,14 +4406,11 @@ istanbul-lib-coverage@^3.0.0: integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== istanbul-lib-instrument@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6" - integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== dependencies: "@babel/core" "^7.7.5" - "@babel/parser" "^7.7.5" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" "@istanbuljs/schema" "^0.1.2" istanbul-lib-coverage "^3.0.0" semver "^6.3.0" @@ -4420,17 +4424,17 @@ jest-worker@25.1.0: supports-color "^7.0.0" jest-worker@^25.1.0: - version "25.2.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.1.tgz#209617015c768652646aa33a7828cc2ab472a18a" - integrity sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ== + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" + integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== dependencies: merge-stream "^2.0.0" supports-color "^7.0.0" -jquery@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" - integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== +jquery@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" + integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4460,16 +4464,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-parse-even-better-errors@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.2.0.tgz#304d29aa54bb01156a1328c454034ff0ac8a7bf4" - integrity sha512-2tLgY7LRNZ9Hd6gmCuBG5/OjRHQpSgJQqJoYyLLOhUgn8LdOYrjaZLcxkWnDads+AD/haWWioPNziXQcgvQJ/g== - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -4498,9 +4497,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" - integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: minimist "^1.2.5" @@ -4511,7 +4510,7 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonparse@^1.3.1: +jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= @@ -4694,9 +4693,9 @@ log-symbols@^3.0.0: chalk "^2.4.2" loglevel@^1.6.6: - version "1.6.7" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56" - integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A== + version "1.6.8" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" + integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== loose-envify@^1.0.0: version "1.4.0" @@ -4728,32 +4727,28 @@ make-dir@^2.0.0: semver "^5.6.0" make-dir@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" - integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -make-fetch-happen@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.4.tgz#d3451baf5b43d6230c4eea7009c5aa6b6bccf9d4" - integrity sha512-hIFoqGq1db0QMiy/Atr/pI1Rs4rDV+ZdGSey2SQyF3KK3u1z4aj9mS5UdNnZkdQpA+H3pGn0J3KlEwsi2x4EqA== - dependencies: - agentkeepalive "^4.1.0" - cacache "^15.0.0" - http-cache-semantics "^4.0.4" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" +make-fetch-happen@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" + integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== + dependencies: + agentkeepalive "^3.4.1" + cacache "^12.0.0" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.3" lru-cache "^5.1.1" - minipass "^3.0.0" - minipass-collect "^1.0.2" - minipass-fetch "^1.1.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" promise-retry "^1.1.1" - socks-proxy-agent "^5.0.0" - ssri "^8.0.0" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" mamacro@^0.0.3: version "0.0.3" @@ -4882,17 +4877,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.43.0" + mime-db "1.44.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" @@ -4900,9 +4895,9 @@ mime@1.6.0, mime@^1.4.1: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + version "2.4.5" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.5.tgz#d8de2ecb92982dedbb6541c9b6841d7f218ea009" + integrity sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w== mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" @@ -4948,18 +4943,6 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.1.2, minipass-fetch@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.2.1.tgz#1b97ecb559be56b09812d45b2e9509f1f59ece2f" - integrity sha512-ssHt0dkljEDaKmTgQ04DQgx2ag6G2gMPxA5hpcsoeTbfDgRf2fC2gNSRc6kISjD7ckCpHwwQvXxuTBK8402fXg== - dependencies: - minipass "^3.1.0" - minipass-pipeline "^1.2.2" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -4967,29 +4950,14 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - minipass-pipeline@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" - integrity sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + version "1.2.3" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz#55f7839307d74859d6e8ada9c3ebe72cec216a34" + integrity sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ== dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: +minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== @@ -4997,10 +4965,10 @@ minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: safe-buffer "^5.1.2" yallist "^3.0.0" -minipass@^3.0.0, minipass@^3.0.1, minipass@^3.1.0, minipass@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== dependencies: yallist "^4.0.0" @@ -5011,7 +4979,7 @@ minizlib@^1.2.1: dependencies: minipass "^2.9.0" -minizlib@^2.0.0, minizlib@^2.1.0: +minizlib@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== @@ -5044,21 +5012,21 @@ mixin-deep@^1.2.0: is-extendable "^1.0.1" mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1, mkdirp@~0.5.x: - version "0.5.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" - integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" mkdirp@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" - integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== moment@>=2.13.0, moment@^2.18.1: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + version "2.25.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.25.3.tgz#252ff41319cf41e47761a1a88cab30edfe9808c0" + integrity sha512-PuYv0PHxZvzc15Sp8ybUCoQ+xpyPWvjOuK72a5ovzp2LI32rJXOiIfyoFoYvG3s6EwwrdkMyWuRiEHSZRLJNdg== move-concurrently@^1.0.1: version "1.0.1" @@ -5106,9 +5074,9 @@ mute-stream@0.0.8: integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== nanomatch@^1.2.9: version "1.2.13" @@ -5127,15 +5095,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -needle@^2.2.1: - version "2.3.3" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.3.tgz#a041ad1d04a871b0ebb666f40baaf1fb47867117" - integrity sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -5159,6 +5118,15 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-fetch-npm@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" + integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -5193,36 +5161,12 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-pre-gyp@*: - version "0.14.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" - integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4.4.2" - node-releases@^1.1.53: - version "1.1.53" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" - integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== + version "1.1.55" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.55.tgz#8af23b7c561d8e2e6e36a46637bab84633b07cee" + integrity sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w== -nopt@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.0.0: +normalize-package-data@^2.0.0, normalize-package-data@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -5264,7 +5208,7 @@ normalize-url@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== -npm-bundled@^1.0.1, npm-bundled@^1.1.1: +npm-bundled@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== @@ -5283,7 +5227,7 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@8.0.1, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1: +npm-package-arg@8.0.1, npm-package-arg@^8.0.0: version "8.0.1" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.0.1.tgz#9d76f8d7667b2373ffda60bb801a27ef71e3e270" integrity sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ== @@ -5292,7 +5236,17 @@ npm-package-arg@8.0.1, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1: semver "^7.0.0" validate-npm-package-name "^3.0.0" -npm-packlist@^1.1.6: +npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" + integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== + dependencies: + hosted-git-info "^2.7.1" + osenv "^0.1.5" + semver "^5.6.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.12: version "1.4.8" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== @@ -5301,17 +5255,7 @@ npm-packlist@^1.1.6: npm-bundled "^1.0.1" npm-normalize-package-bin "^1.0.1" -npm-packlist@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.1.tgz#08806a1df79acdc43d02d20c83a3d5472d96c90c" - integrity sha512-95TSDvGwujIhqfSpIiRRLodEF+y6mJMopuZdahoGzqtRDFZXGav46S0p6ngeWaiAkb5R72w6eVARhzej0HvZeQ== - dependencies: - glob "^7.1.6" - ignore-walk "^3.0.3" - npm-bundled "^1.1.1" - npm-normalize-package-bin "^1.0.1" - -npm-pick-manifest@6.0.0, npm-pick-manifest@^6.0.0: +npm-pick-manifest@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.0.0.tgz#bfde7abe95f2670aed1629a3c18245ccb3cc2eb8" integrity sha512-PdJpXMvjqt4nftNEDpCgjBUF8yI3Q3MyuAmVB9nemnnCg32F4BPL/JFBfdj8DubgHCYUFQhtLWmBPvdsFtjWMg== @@ -5320,19 +5264,27 @@ npm-pick-manifest@6.0.0, npm-pick-manifest@^6.0.0: npm-package-arg "^8.0.0" semver "^7.0.0" -npm-registry-fetch@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-8.0.0.tgz#65bb51dd2b9634b8363019aac9c76c003e5c5eaf" - integrity sha512-975WwLvZjX97y9UWWQ8nAyr7bw02s9xKPHqvEm5T900LQsB1HXb8Gb9ebYtCBLSX+K8gSOrO5KS/9yV/naLZmQ== +npm-pick-manifest@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" + integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-registry-fetch@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.4.tgz#2da1ecf3f43d419d96abf313664291a4623d3ea5" + integrity sha512-6jb34hX/iYNQebqWUHtU8YF6Cjb1H6ouTFPClYsyiW6lpFkljTpdeftm53rRojtja1rKAvKNIIiTS5Sjpw4wsA== dependencies: - "@npmcli/ci-detect" "^1.0.0" + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" lru-cache "^5.1.1" - make-fetch-happen "^8.0.2" - minipass "^3.0.0" - minipass-fetch "^1.1.2" - minipass-json-stream "^1.0.1" - minizlib "^2.0.0" - npm-package-arg "^8.0.0" + make-fetch-happen "^5.0.0" + npm-package-arg "^6.1.0" + safe-buffer "^5.2.0" npm-run-path@^2.0.0: version "2.0.2" @@ -5341,16 +5293,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -5392,10 +5334,13 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== -object-is@^1.0.1, object-is@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== +object-is@^1.0.1, object-is@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -5535,7 +5480,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: +osenv@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -5566,9 +5511,9 @@ p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -5622,34 +5567,41 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pacote@11.1.4: - version "11.1.4" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.1.4.tgz#5529a453c59881b7f059da8af6903b0f79c124b2" - integrity sha512-eUGJvSSpWFZKn3z8gig/HgnBmUl6gIWByIIaHzSyEr3tOWX0w8tFEADXtpu8HGv5E0ShCeTP6enRq8iHKCHSvw== - dependencies: - "@npmcli/git" "^2.0.1" - "@npmcli/installed-package-contents" "^1.0.5" - "@npmcli/promise-spawn" "^1.1.0" - cacache "^15.0.0" - chownr "^1.1.4" - fs-minipass "^2.1.0" +pacote@9.5.12: + version "9.5.12" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" + integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== + dependencies: + bluebird "^3.5.3" + cacache "^12.0.2" + chownr "^1.1.2" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" infer-owner "^1.0.4" lru-cache "^5.1.1" - minipass "^3.0.1" - minipass-fetch "^1.2.1" - mkdirp "^1.0.3" - npm-package-arg "^8.0.1" - npm-packlist "^2.1.0" - npm-pick-manifest "^6.0.0" - npm-registry-fetch "^8.0.0" + make-fetch-happen "^5.0.0" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-normalize-package-bin "^1.0.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^3.0.0" + npm-registry-fetch "^4.0.0" + osenv "^0.1.5" promise-inflight "^1.0.1" promise-retry "^1.1.1" - read-package-json-fast "^1.1.3" - rimraf "^2.7.1" - semver "^7.1.3" - ssri "^8.0.0" - tar "^6.0.1" - which "^2.0.2" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.10" + unique-filename "^1.1.1" + which "^1.3.1" pako@~1.0.5: version "1.0.11" @@ -5665,7 +5617,7 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" -parse-asn1@^5.0.0: +parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.5" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== @@ -5768,7 +5720,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.7: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -5827,9 +5779,9 @@ popper.js@^1.16.1: integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== portfinder@^1.0.25: - version "1.0.25" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" - integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg== + version "1.0.26" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== dependencies: async "^2.6.2" debug "^3.1.1" @@ -5986,6 +5938,39 @@ postcss-minify-selectors@^4.0.2: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + postcss-normalize-charset@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" @@ -6105,7 +6090,7 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.2: +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== @@ -6138,12 +6123,12 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" - integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@7.0.27, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.26, postcss@^7.0.27: +postcss@7.0.27: version "7.0.27" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== @@ -6152,6 +6137,15 @@ postcss@7.0.27, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.26, postcss@^7.0.27 source-map "^0.6.1" supports-color "^6.1.0" +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.30" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.30.tgz#cc9378beffe46a02cbc4506a0477d05fcea9a8e2" + integrity sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + prepend-http@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -6199,6 +6193,13 @@ propagating-hammerjs@^1.4.6: dependencies: hammerjs "^2.0.8" +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -6345,16 +6346,6 @@ raw-loader@4.0.0: loader-utils "^1.2.3" schema-utils "^2.5.0" -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - read-cache@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" @@ -6362,14 +6353,6 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -read-package-json-fast@^1.1.1, read-package-json-fast@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-1.1.3.tgz#3b78464ea8f3c4447f3358635390b6946dc0737e" - integrity sha512-MmFqiyfCXV2Dmm4jH24DEGhxdkUDFivJQj4oPZQPOKywxR7HWBE6WnMWDAapfFHi3wm1b+mhR+XHlUH0CL8axg== - dependencies: - json-parse-even-better-errors "^2.0.1" - npm-normalize-package-bin "^1.0.1" - read-package-json@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.1.tgz#16aa66c59e7d4dad6288f179dd9295fd59bb98f1" @@ -6391,7 +6374,7 @@ read-package-tree@5.3.1: readdir-scoped-modules "^1.0.0" util-promisify "^2.1.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6404,7 +6387,7 @@ read-package-tree@5.3.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6: +readable-stream@^3.0.6, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -6413,7 +6396,7 @@ readable-stream@^3.0.6: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0: +readdir-scoped-modules@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== @@ -6432,12 +6415,12 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" - integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== dependencies: - picomatch "^2.0.7" + picomatch "^2.2.1" reflect-metadata@^0.1.2: version "0.1.13" @@ -6588,9 +6571,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" @@ -6634,7 +6617,7 @@ rimraf@3.0.2: dependencies: glob "^7.1.3" -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -6657,11 +6640,9 @@ rollup@2.1.0: fsevents "~2.1.2" run-async@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" - integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== - dependencies: - is-promise "^2.1.0" + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" @@ -6670,22 +6651,29 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@6.5.4, rxjs@^6.5.2, rxjs@^6.5.3: +rxjs@6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== dependencies: tslib "^1.9.0" +rxjs@^6.5.2, rxjs@^6.5.3: + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex@^1.1.0: version "1.1.0" @@ -6717,7 +6705,7 @@ sass@1.26.3: dependencies: chokidar ">=2.0.0 <4.0.0" -sax@^1.2.4, sax@~1.2.4: +sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -6732,9 +6720,9 @@ schema-utils@^1.0.0: ajv-keywords "^3.1.0" schema-utils@^2.5.0, schema-utils@^2.6.1, schema-utils@^2.6.4, schema-utils@^2.6.5: - version "2.6.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" - integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + version "2.6.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" + integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== dependencies: ajv "^6.12.0" ajv-keywords "^3.4.1" @@ -6775,7 +6763,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.1.3, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3: +semver@7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== @@ -6785,6 +6773,11 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.0.0, semver@^7.1.1: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -6832,7 +6825,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -6969,16 +6962,15 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== +socks-proxy-agent@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" + agent-base "~4.2.1" + socks "~2.3.2" -socks@^2.3.3: +socks@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== @@ -7017,10 +7009,10 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@0.5.16, source-map-support@^0.5.5, source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== +source-map-support@^0.5.5, source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -7059,14 +7051,14 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -7089,9 +7081,9 @@ spdy-transport@^3.0.0: wbuf "^1.7.3" spdy@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" - integrity sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== dependencies: debug "^4.1.0" handle-thing "^2.0.0" @@ -7138,7 +7130,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^6.0.1: +ssri@^6.0.0, ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== @@ -7224,7 +7216,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -7242,9 +7234,9 @@ string-width@^4.1.0, string-width@^4.2.0: strip-ansi "^6.0.0" string.prototype.trimend@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373" - integrity sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA== + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== dependencies: define-properties "^1.1.3" es-abstract "^1.17.5" @@ -7268,9 +7260,9 @@ string.prototype.trimright@^2.1.1: string.prototype.trimend "^1.0.0" string.prototype.trimstart@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz#afe596a7ce9de905496919406c9734845f01a2f2" - integrity sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w== + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== dependencies: define-properties "^1.1.3" es-abstract "^1.17.5" @@ -7315,11 +7307,6 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - style-loader@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.1.3.tgz#9e826e69c683c4d9bf9db924f85e9abb30d5e200" @@ -7415,7 +7402,7 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^4.4.2: +tar@^4.4.10: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== @@ -7429,11 +7416,11 @@ tar@^4.4.2: yallist "^3.0.3" tar@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.1.tgz#7b3bd6c313cb6e0153770108f8d70ac298607efa" - integrity sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q== + version "6.0.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39" + integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg== dependencies: - chownr "^1.1.3" + chownr "^2.0.0" fs-minipass "^2.0.0" minipass "^3.0.0" minizlib "^2.1.0" @@ -7470,19 +7457,19 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser@4.6.7: - version "4.6.7" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" - integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== +terser@4.6.10: + version "4.6.10" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.10.tgz#90f5bd069ff456ddbc9503b18e52f9c493d3b7c2" + integrity sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA== dependencies: commander "^2.20.0" source-map "~0.6.1" source-map-support "~0.5.12" terser@^4.1.2, terser@^4.4.3: - version "4.6.10" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.10.tgz#90f5bd069ff456ddbc9503b18e52f9c493d3b7c2" - integrity sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA== + version "4.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.7.0.tgz#15852cf1a08e3256a80428e865a2fa893ffba006" + integrity sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -7496,7 +7483,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@X.X.X, through@^2.3.6: +"through@>=2.2.7 <3", through@X.X.X, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -7623,11 +7610,16 @@ tree-kill@1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -tslib@1.11.1, tslib@^1.10.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== +tslib@^1.10.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + tslint@^5.12.1: version "5.20.1" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" @@ -7689,16 +7681,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@3.6.5: + version "3.6.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.5.tgz#dae20114a7b4ff4bd642db9c8c699f2953e8bbdb" + integrity sha512-BEjlc0Z06ORZKbtcxGrIvvwYs5hAnuo6TKdNFL55frVDlB+na3z5bsLhFaIxmT+dPWgBIjMo6aNnTOgHHmHgiQ== + typescript@3.7.5: version "3.7.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== -typescript@3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" - integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== - unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -7932,14 +7924,23 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack@^1.6.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" - integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== +watchpack-chokidar2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" + integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== dependencies: chokidar "^2.1.8" + +watchpack@^1.6.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa" + integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g== + dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.0" + watchpack-chokidar2 "^2.0.0" wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" @@ -8109,38 +8110,25 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-typed-array@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.1.tgz#bff075fd975faedad9ed9355ee0d15452d068794" - integrity sha512-IWlkoJZ4Zdfi4YBn2wnYB8AVox+4A2+Kmr4kHFAraffHYrQZFiTOjgjk9et8e6RSPZOV1QjZOC51PVCK9SkR/A== +which-typed-array@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" + integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== dependencies: - available-typed-arrays "^1.0.1" - es-abstract "^1.17.4" + available-typed-arrays "^1.0.2" + es-abstract "^1.17.5" + foreach "^2.0.5" function-bind "^1.1.1" has-symbols "^1.0.1" is-typed-array "^1.1.3" -which@^1.2.9: +which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -8148,10 +8136,10 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" -worker-plugin@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/worker-plugin/-/worker-plugin-4.0.2.tgz#0456dd7af1c0de64591326fd8a08c5d9f2b5b27a" - integrity sha512-V+1zSZMOOKk+uBzKyNIODLQLsx59zSIOaI75J1EMS0iR1qy+KQR3y/pQ3T0vIhvPfDFapGRMsoMvQNEL3okqSA== +worker-plugin@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/worker-plugin/-/worker-plugin-4.0.3.tgz#7c42e600d5931ad154d3d5f187a32446df64db0f" + integrity sha512-7hFDYWiKcE3yHZvemsoM9lZis/PzurHAEX1ej8PLCu818Rt6QqUAiDdxHPCKZctzmhqzPpcFSgvMCiPbtooqAg== dependencies: loader-utils "^1.1.0" @@ -8184,10 +8172,10 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -xhr2@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" - integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= +xhr2@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.2.0.tgz#eddeff782f3b7551061b8d75645085269396e521" + integrity sha512-BDtiD0i2iKPK/S8OAZfpk6tyzEDnKKSjxWHcMBVmh+LuqJ8A32qXTyOx+TVOg2dKvq6zGBq2sgKPkEeRs1qTRA== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" @@ -8218,9 +8206,9 @@ yargs-parser@^11.1.1: decamelize "^1.2.0" yargs-parser@^18.1.0: - version "18.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1" - integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ== + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" From e23ec43043dd7dc300f4137f6f6a92f6b937b21a Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 20 May 2020 18:49:34 +0200 Subject: [PATCH 018/237] Dependency resolution improvements --- build.gradle | 5 +++-- camel-multipart-processor/build.gradle.kts | 4 +--- ids-acme/build.gradle.kts | 4 +--- ids-endpoint-config/build.gradle | 2 +- ids-infomodel-manager/build.gradle.kts | 4 +--- ids-settings/build.gradle.kts | 4 +--- ids-token-manager/build.gradle | 2 +- 7 files changed, 9 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 315587330..9812a5ed5 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,9 @@ plugins { id "com.github.jk1.dependency-license-report" version "1.2" } +ext.set("libraryVersions", + new Yaml().loadAs(new FileInputStream(file("${rootDir}/libraryVersions.yaml")), Map.class)) + licenseReport { configurations = ["compile", "providedByFeature", "providedByBundle"] } @@ -31,8 +34,6 @@ allprojects { group = "de.fhg.aisec.ids" version = "3.0.2" - ext.libraryVersions = new Yaml().loadAs(new FileInputStream(file("${rootDir}/libraryVersions.yaml")), Map.class) - configurations { // just to make bills of materials (bom) easier to see in the dependency tree bom diff --git a/camel-multipart-processor/build.gradle.kts b/camel-multipart-processor/build.gradle.kts index 490143d8f..b8e816932 100644 --- a/camel-multipart-processor/build.gradle.kts +++ b/camel-multipart-processor/build.gradle.kts @@ -1,8 +1,6 @@ -import org.yaml.snakeyaml.Yaml - dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + rootProject.ext.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-acme/build.gradle.kts b/ids-acme/build.gradle.kts index 98140f16b..f8ad8680f 100644 --- a/ids-acme/build.gradle.kts +++ b/ids-acme/build.gradle.kts @@ -1,8 +1,6 @@ -import org.yaml.snakeyaml.Yaml - dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + rootProject.ext.get("libraryVersions") as Map providedByBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-endpoint-config/build.gradle b/ids-endpoint-config/build.gradle index 26347138e..fa2ef315e 100644 --- a/ids-endpoint-config/build.gradle +++ b/ids-endpoint-config/build.gradle @@ -3,7 +3,7 @@ dependencies { osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - testImplementation group: 'junit', name: 'junit' + testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito } diff --git a/ids-infomodel-manager/build.gradle.kts b/ids-infomodel-manager/build.gradle.kts index 4efb6216d..041690bba 100644 --- a/ids-infomodel-manager/build.gradle.kts +++ b/ids-infomodel-manager/build.gradle.kts @@ -1,8 +1,6 @@ -import org.yaml.snakeyaml.Yaml - dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + rootProject.ext.get("libraryVersions") as Map infomodelBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-settings/build.gradle.kts b/ids-settings/build.gradle.kts index 1861aaf39..a07b0682c 100644 --- a/ids-settings/build.gradle.kts +++ b/ids-settings/build.gradle.kts @@ -1,8 +1,6 @@ -import org.yaml.snakeyaml.Yaml - dependencies { @Suppress("UNCHECKED_CAST") val libraryVersions = - Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + rootProject.ext.get("libraryVersions") as Map infomodelBundle(project(":ids-api")) { isTransitive = false } diff --git a/ids-token-manager/build.gradle b/ids-token-manager/build.gradle index 200d315b4..297a6459f 100755 --- a/ids-token-manager/build.gradle +++ b/ids-token-manager/build.gradle @@ -11,7 +11,7 @@ dependencies { providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: libraryVersions.jose4j providedByBundle group: 'org.json', name: 'json', version: libraryVersions.orgJson - testImplementation group: 'junit', name: 'junit' + testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito } From 395b2d7566cc3a1254886404f2969e3b3a80cd09 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 25 May 2020 19:21:56 +0200 Subject: [PATCH 019/237] Fixed DockerCmIT --- .../test/java/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.java b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.java index b82112778..bfc81a289 100644 --- a/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.java +++ b/ids-container-manager/src/test/java/de/fhg/aisec/ids/cm/impl/docker/DockerCmIT.java @@ -90,9 +90,9 @@ public void testVersion() { DockerCM d = new DockerCM(); - var version = d.getVersion(); + final var version = d.getVersion(); assertFalse(version.isEmpty()); - var regex = ".* \\([0-9.]+(?:-.+)?\\)"; + final var regex = ".* \\([0-9.]+(?:.+)?\\)"; if (!version.matches(regex)) { throw new AssertionError( "Error: Docker version has to match regex '" + regex + "', found '" + version + "'"); From bbfa79f751aecaec326c285a209ef978c24b8075 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 18:55:07 +0200 Subject: [PATCH 020/237] Reduced PDP log verbosity --- .../ids/dataflowcontrol/PolicyDecisionPoint.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ids-dataflow-control/src/main/java/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt b/ids-dataflow-control/src/main/java/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt index c3b7a2d0d..91c56d119 100644 --- a/ids-dataflow-control/src/main/java/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt +++ b/ids-dataflow-control/src/main/java/de/fhg/aisec/ids/dataflowcontrol/PolicyDecisionPoint.kt @@ -216,21 +216,21 @@ class PolicyDecisionPoint : PDP, PAP { override fun requestDecision(req: DecisionRequest): PolicyDecision { val dec = PolicyDecision() - - LOG.debug( - "Decision requested " + req.from.endpoint + " -> " + req.to.endpoint) + if (LOG.isTraceEnabled) { + LOG.trace("Decision requested " + req.from.endpoint + " -> " + req.to.endpoint) + } try { // Query Prolog engine for a policy decision val startTime = System.nanoTime() val query = this.createDecisionQuery(req.to, req.properties) - if (LOG.isDebugEnabled) { - LOG.debug("Decision query: {}", query) + if (LOG.isTraceEnabled) { + LOG.trace("Decision query: {}", query) } val solveInfo = this.engine.query(query, true) val time = System.nanoTime() - startTime - if (LOG.isInfoEnabled) { - LOG.debug("Decision query took {} ms", time / 1e6f) + if (LOG.isTraceEnabled) { + LOG.trace("Decision query took {} ms", time / 1e6f) } // If there is no matching rule, deny by default From 4c8bf37d53e5e42ebf42cb33e8a4058326cfe9b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2020 13:48:57 +0000 Subject: [PATCH 021/237] Bump websocket-extensions in /ids-webconsole/src/main/resources/www Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot[bot] --- ids-webconsole/src/main/resources/www/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ids-webconsole/src/main/resources/www/yarn.lock b/ids-webconsole/src/main/resources/www/yarn.lock index 4df1f4087..a2e3ebddf 100644 --- a/ids-webconsole/src/main/resources/www/yarn.lock +++ b/ids-webconsole/src/main/resources/www/yarn.lock @@ -8075,9 +8075,9 @@ websocket-driver@>=0.5.1: websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== when@~3.6.x: version "3.6.4" From ad66e4368b7098ad95b775661d7a0b69afa1d517 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 30 Oct 2019 12:48:37 +0100 Subject: [PATCH 022/237] Created module skeleton --- idscp2/.gitignore | 5 + idscp2/LICENSE.txt | 201 ++++++++++++++++++ idscp2/README.md | 1 + idscp2/bnd.bnd | 7 + idscp2/build.gradle | 26 +++ .../test/resources/jsse/client-keystore.jks | Bin 0 -> 2495 bytes .../test/resources/jsse/client-truststore.jks | Bin 0 -> 1954 bytes .../test/resources/jsse/server-keystore.jks | Bin 0 -> 4494 bytes .../test/resources/jsse/server-truststore.jks | Bin 0 -> 1954 bytes idscp2/src/test/resources/log4j2-test.xml | 39 ++++ settings.gradle | 1 + 11 files changed, 280 insertions(+) create mode 100644 idscp2/.gitignore create mode 100644 idscp2/LICENSE.txt create mode 100644 idscp2/README.md create mode 100644 idscp2/bnd.bnd create mode 100644 idscp2/build.gradle create mode 100644 idscp2/src/test/resources/jsse/client-keystore.jks create mode 100644 idscp2/src/test/resources/jsse/client-truststore.jks create mode 100644 idscp2/src/test/resources/jsse/server-keystore.jks create mode 100644 idscp2/src/test/resources/jsse/server-truststore.jks create mode 100644 idscp2/src/test/resources/log4j2-test.xml diff --git a/idscp2/.gitignore b/idscp2/.gitignore new file mode 100644 index 000000000..74007849d --- /dev/null +++ b/idscp2/.gitignore @@ -0,0 +1,5 @@ +/target/ +/bin/ +/generated/ +/.classpath +/build.properties diff --git a/idscp2/LICENSE.txt b/idscp2/LICENSE.txt new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/idscp2/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/idscp2/README.md b/idscp2/README.md new file mode 100644 index 000000000..990171e66 --- /dev/null +++ b/idscp2/README.md @@ -0,0 +1 @@ +The _ids-comm_ module wraps the IDSCP, providing secure communication and remote attestation between Connector instances. diff --git a/idscp2/bnd.bnd b/idscp2/bnd.bnd new file mode 100644 index 000000000..379857898 --- /dev/null +++ b/idscp2/bnd.bnd @@ -0,0 +1,7 @@ +Bundle-Name: IDS :: IDS Communication Protocol +Bundle-Description: IDS Communication Protocol +Export-Package: \ + de.fhg.aisec.ids.comm* +Import-Package: \ + !org.checkerframework.checker*,\ + * \ No newline at end of file diff --git a/idscp2/build.gradle b/idscp2/build.gradle new file mode 100644 index 000000000..a781231a9 --- /dev/null +++ b/idscp2/build.gradle @@ -0,0 +1,26 @@ +version = libraryVersions.idscp + +dependencies { + providedByBundle(project(':ids-api')) { transitive = false } + + providedByBundle group: 'com.github.microsoft', name: 'TSS.Java', version: '0.3.0' + + providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j + providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j + + providedByBundle group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf + + publishCompile group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual + + providedByBundle group: 'org.asynchttpclient', name: 'async-http-client', version: libraryVersions.ahc + + providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-server', version: libraryVersions.jetty + providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-client', version: libraryVersions.jetty + + testImplementation group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb + testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb + testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb + + testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 + testImplementation group: 'org.mockito', name: 'mockito-all', version: libraryVersions.mockito +} diff --git a/idscp2/src/test/resources/jsse/client-keystore.jks b/idscp2/src/test/resources/jsse/client-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..1a296db9f9a1a905aab56457e5faa5aa0c55b332 GIT binary patch literal 2495 zcmZuydpMNo8=i0G8^#ARgpqQ}tWi0JgqnN>YHI?iYR*_B@Mmx!`ttg+W9?Dlb=!Z8xLu^rKg5U1@|%TMeLRVnTb>%(XEHC z+iHMbZR0$e%5pJFBkc3EFBJPYo*9^a9nAi)Qf9lwE^M&b=6vNlyp^ZlE)Bg6Nko4E zU631*>?2Ll40u1>uUW;`YfXr{HGDc*GH@r?VyjPH)LS1rrTpeT7InC*%v5mOozTJ3f|FS{%0sz z--dKVd4Ew$l=LMe6y5()EClCwP#-e%ks@k`#&%nBa7|76WwW?*Jk!O^=g50%Zv^4B z5AhEyK6My5IV(CW>lzJI3yUBThfTUqTc6bXUbZXf0dG%i?v`KYH*2ec+!I=s{a7Po zvcl?+IK*vpjH_1h1YXBUdeFGcgM0UOyLhZu0gXjz#EvfovTo}XtM0xaSrU$9 zV;QP!7;2~_z#40{aCeV)(n#QVk^dREQCYm_6s$nlA|(_{Y1u-}+dWAyY;KtJ^k(n+JA^zEVMw_`v1w3^Efs4=UU z^$Q6D{4ow=^Q@Wg0B)bqFwXE*1EQhey8hTjN6C+$>eqILCuLVMV>bq2ltVsrC0FWH zG2>?fjA>cVN0+QaT5Ood72DJHSg?1M7Ch>X)4b+%w>44rgM@#iR4@P3$M7I}P~@?h zw#OH9v3zP*)h!zDy!gx5EfZiUFl$?dVSvQ$4lsoCcFSXn9$PxjSB>E64P^RZ@2d?LL@g zx6Le09${MEOqQ*sxw^hpp2)_PIKQ}Z`=xH0uz+f`y~8Nx*~w4d!8=G0PnT6XOZz$% z(YqlVcoPBv9+pqUcvygv`}JAT?izYXbZ2#s}XI9FiBp^2DY&d zmP5OLLHN-BldH>%%XySA3R~$(5u6wz4pv`IC}Na6c@Z&;{Sh($EdUE+md~kT&@S8j zzHue4gzhbyF z2ATUIkMEY6y*QFCW40jA;MVLK%TNN_t8_5h-%!1Ex(zySCS6@;>=2bun|w3rl^^r& z@H$QQM0{e>q0Xt;myHg2`QbOM0`i|&h~KCjP12!iKiwI0Eb%i5+eiVNb~^Tyn~FvE zY2Wh`=5z^t@drE~d@OOTf023jyX5erSAF&2zUd-C+gym{&*BR{(buWElPa1USCJ`U z^puI+El}Frcx0W3EAj9D8LR?6ij50vnOnyHfG@LnZ8^?sS7c0uwuVHiJiSMA;7;)sO-O0(A89A!Yo544 zE_sl5FnwnxM-=d;ckc9sV>cg!S*YYN3NreM>JM*p?=@XjF)ZPS5R}JfPIvZp9&Wgy zeZ;dwZ|7u{wny~ueM7-&7pm*7;atnTCh%W$#XHQ_qFz8X75h0jS;4`eO-r@!Ayw-m vzBj!eU8}##_KO;_e`T)owl{P|`L_lqUG?i05<5)mu+0@`1t|N}%b|Y)9u*Bp literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/jsse/client-truststore.jks b/idscp2/src/test/resources/jsse/client-truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..eebd40f4c4da3ded8f6a3a60042f0812e1a3b4b1 GIT binary patch literal 1954 zcmezO_TO6u1_mZLW=c+EU|VGZP~d6DPw* z#)ZZgw$)V{@Un4gwRyCC=VfGMWo0n1HRLwnWMd9xVH0L@aWxb+5Cn0!c(~k(5=-+k z^3zg_3?&W3L4wRY0-i3x3PJh#B?``t3PuKoW(IQNyoP3m21YIbQ53xn&{ zeeaKbu+wmVuBJ0fL};VO;gva4Z@b++dT+b$;;*OX)!HjXDkL9CG?IDVRCS@>JAlD+ zQS1B*8l^wHH>KZpSRLCT%(83y;r`Xey1 zX-?8|%`1w__l344{FYAL%D(8+zth|+g7){`pFj7t*(BBGS0`VqxJ=a`|JCzdDJ5mXkD`xyeE7Hf4C}H7GT-kP?00S! zUn_ZZe$Rz+^Rh>rZ}`QZ?%rveT5-Vc3@Svzn1d@mwsQVDx-U;=gzJO+&p)d{L&}ed8U`Xv|J#?B;5Znv+J*;+hQk1?0mFAL*VBkhGn0oy6-JKaMx1zQjG6;y{mf5_U;oq z=5xThx|sQrj_|6Pk9aRFozpT;dd|GS#?rYRr3)we=>9G}b5TZs??t0U<_qC&O_!~U zGQQlsHBY5))7x$LFK@Z{fb*irqcd5KS-Oigk1de?SKU{eXzkPVXS#ULw+C%|H~h%? zyypHt^*L(h7yH*`oQkgbvfbwmht@6W<9qtT&A|DOwYW41mi>$lBeLHMVD@_g%zkGe z*^iMCIRv?Bk?o93fZ5I%mhG&G$kpNoqQEEy=4w7rt`06ug5_yKneJ6~!Vb}x`@eqN zQCPSADgXLbaml@!`^sneB*$HN^6==AiD{RXP0df`5%u{K*ewvlx;MCTrEOz@gNwiD z@1I{@IoA5{PVTyEQJ|=JqI+{#F(zj3fhglyE1tE#+^tn`Q8c@* z>~(?bwvLR~r--eo0>#U8oAl zbd4Vj8s8#iyU(phUFHic-?zRmC#0C&@bqv0;zr7{U7LY9C=bfB7#Qdo=q%7$pwXt5 zQBqQ1rLUh{l%toJS)7`zmj*AU^-@yxGgFH7fN};QY#iEb!1A4)k&(s2z|Ft~#y4PU zvw)hBl3$*elb;CGfz6~MU@4!Rn4DTv0xIYAKn%1r3@!!cuJ4(^`8iPfliCE?!s!nE zG9S6pZ^Sh!d%j(@oM&Q5#XFYD51=`u78&@%dR=X2lBHEjR%|Gxfq zld(MM^Cp|32YnOo-8-zi=Z;LA*FuT!RzA)9k7if!PFvdZa>LW7C9kF&SjJTDRx`Kw zNpFL<;!AFc$4_@Smj#L~+|;okV_k9cjra{8R<2ao)2g&_y-=oAo#OZUHvjx9J<}(o z*nKLJxi*O}Zq>$kmbhR?g9$ltr;bl|-Ku4G>1SK|SG@!c=Q(i+MVGe9&Sh79EZwkm z_PsrBqM|EXvr6uS@Y%gx!XY?sYiv*Z!4~nHT;H^*$E!}u96Zz4qxm$qaG`0!$_rC& SIRsq4$r!~{@WDl3D?0!nu;#!3 literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/jsse/server-keystore.jks b/idscp2/src/test/resources/jsse/server-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..5e8f8003fce1cb4f166cd15a7a359cfbcbc20c16 GIT binary patch literal 4494 zcmaJ^c|25Y|DMeK(ap7;GczuzC{^SQ5c-}iOC_xF6y_qxu>`pG&71cLnY0)xnIVX#;n2n2S1 z?D=yS1R?_ic-S#OM@}V54u*j*KG7t<8Tej|g@!d%$&@9Di+iZOxG9G!BW zQMqk)RKwU^o_f6&^(orgd{=IiFL6cpf>9%NBCgMPcRYZiov7LTz1C8W%F}VM=A1Mv zE;y~p;q_v)`%|n$%eJ$v*@D8Y$&x*vn~jJY`@U|f%ZfLndPei9w`JHxhl28~On&t4 z58{7n!yZW(ouSg=nak#qU6)~4yZyDUbtvkJn!n5Lroc`PZ`Hv^)0^mUELE;@h!i0{ z$F{biv65eJR^I<*wt2|om95KfQ~O8IYu_y$=jreB5O0XeFvMvTn(prf+&A{E(q-U3 zKo5x=vGE*gsIxDHcAg#yxnxC^HqM9SgXS9Vf91No^@UgqoUvi&B%?nZQS2%D1H=0r zox-g6mW2g!`#35t^^)?Ze+S@2Q@dR@S^KXGTk>TTbxP$-E~pb$|8#Fi4(t; zq7iNC`--YsbjzZ(X3px6JCj^AW|6Y>Yi-L1$A`2oI_7FQ(OcZq%`zCZrTw=a?@zWM z6lGC2_4GZ2S(3D$;x2J=uZGp0>sbtZFUjXf_APHpDn#iG8`WGlnIhSb}`0RAY_mtZszSk_Y)+O9)cZv-Ev!#6%xH(#ZO;s+8pkS7jh(IW145aZP?} z3sz}RuvK@#-9TA7SJA(N%$L4HNAG%jx4!Q5v{>P@*>&5GSG3}18(*?l%axpNSoWKa z4BJ=O-#jlleh~F&K0czIn*D65fjWz0kdK-?P;v2khF4lw^}+G*Big$ z$57*fPG*fMdnczSYNiyKWT}7eTh&1EX~6W1b0A?o>{!WZ)%rI7KKRhf3440_7V^kV zT?=%;ciG5s^<9;~^Yr^V9y*J>EJsD-`?P|~S$&<%p2C^c7JNfl!3M`Oo}U+Y`8GFW zd-vq>!kO&ig*jRIuQ!i9Npf6>zeLp36?sB<{Ob9w!IpVA^^A!uf%}|3zkZ(tsW+1P zqPe&{OP0HCC0EJ;xQFYy1^g$MKgm7dgmp?EL?M2dh4f(L^^ zaZ+|$)klUm^eQYXO-?JP3WIlWqXaeGQB4Xq-Q+3vdCxAt`=a-15R?Vw-rhs%#8!R) zmz=h|@gw(Ivy-Qinhimj@M@93dMw|UWr3kGN1TCxJiP@S+=yx6C_l+R_qTn*PHucVcxUvPiZ$v&dz z^YXkADgbJ78z=dNaG`v$G@X5~AeRv>-qs-7G2G)FFFeb9i(aKa&V#}uc}~gREIM`Z zdR@uFbVz5s-z&j%H0wrPwaYcyR{QkY@QYiY$sqxPG~s(8+0HRT;E5&!Rt8G?hF!Pi260GGBB33(dt zeoknfAKTOdD!aKxi+9>47J4ONDDUfpN%w&cgyl=F-4Fhb2+Ne&`3?W(12ucfxz(TW zvTrqg>1Ac67GzEG)u26^#9~@<8#^iJ+>zc}>lTxfB*e?;iI_LeZj;wai_qTIB{w9P zA+@$GnVi4N7K|hnui2q0w1y<*P?D6N{*9Eco>Pw!o9DBj$*%v@n|PUSCDn2s!5`Xs z;zQ%vM}bz6ndN^=6%yO1A?j|B3uuC|});#=@%ZlUeAW~#EkZ7rc& zhj;o$;>j`X*yp_;mHtA- zZaaY+V;%Mm7_xo~>i}n&+qNN|NS~@hvXlsP=ExuYW2y3C ze%Ef%8x2*RX&*l>FbZyr^)t=M*%(Wt|7`O4xNjt`0oMXk(3=8{-8-B$4(X#-FMCB^ z0eUu~6GYRIvk}`q!;cRxcA3k`UXesg6isCgbwJ-gy98cNHE%QKI!m}0W%w>Jv&!Qe z2T$;7{5|6BhCM0%{u)O7hFKw%S4x)7;hT^EvY)Xo0gltjDPoB3^|A145^bx0Ja1Ou z!yRdzV_N$va|iy^i7n>RgbI6s^uz5lIM{Yh^RSq|VronVWv~a=BmGeSmCG){Qy{5w z^kEXUYj@lv`7pWMZ2dfYr>|nc6~TVL2Q!c?-B3}#QL0CrI7)#}tpV%~M#m+__6Oaw zz2kG*Te%X>i8d~B$z9?-xktyqIyE|rsJMmq@#fncV>W=g_ zjf=}z#g*yX$g6CJ6?n$K_c;0_pqV~FQy-+`Xtdv2mMjUip?aRN7E&KXD1Iz{xR{)W z3U<)=bc5$1CZ+R?ueYRlf(6)(z*qWi*v=-o!Bo9(-=>%Wr5)$RZZj|;Fj(T~H_tHH z6A}bqFlp#A=MF~g`#y_}(SuwRFQwycSky!x0r1>|XK=;U&Z#47v(7SWi_xncj!fqM z)D`$NR$TL@+a8vwg@O=pf?G7KuLt46aN{xC2sv+l7V~N4{!SY@v53qoP4MU?BcJ(l zTB@zDQRf>jsRm}Tm9+7`-c1!8-+N)F%mf?4Y`^f4&&>Iqz4ec zZcxxr>fXk9I=Emw|2_aZfacdaY8ok9yGR|)gE~K$+TMD!SOfFdF_U#C z@)TWvekgb~+VVN~`Uh9pqx$#LiY&!~^l(i?)A}cO7laI!vNn-@@%&6- zb47x?u^$Dp`%up>?04mGFv1`J2%!G876F4nA!J#A>@UCt0|0SAEbBs+aFn167VE7b zA>rWbE^g=Qhj9>h`geVaJ7OeU9sR^fbAT~9CFwVujEn*dhFt};0F8fP01_qlPYy?~ z08e)>JJOE7WAgR#!aCSFV0^K^N>u#U;Ll?Uz?cE1f6+l9{~mz>)nC!l!xR8H{D0gm z9*&fh6(=1)9Es;9h3DYq>4|Z`dinm{Q~%DM`3s;kUN?*q7Qs0wwmkLHL* zma5c6o-efVE~Yg&OiQrtu`UdGB-6QDe<;0@HqaD!;!0C2q|N-y<8Ey}N^3;^jhH3h zF4}i*FR;gz@o_shl+REXbn;Q4OXTn@dYs)U3# z4jbXtYJ>!5ku8WFx9SKl>oQ6z-&L%{QZo;v$7v8?nKXv#E3X<=N10LP+32D|Ul~q3 xTi2Z}@4K}q8t80BrK0L4(d_Gz*0VRpzEVGZP~d6DPw* z#)ZZgw$)V{@Un4gwRyCC=VfGMWo0n1HRLwnWMd9xVH0L@aWxb+5Cn0!c(~k(5=-+k z^3zg_3?&W3L4wRY0-i3x3PJh#B?``t3PuKoW(IQNyoP3m21YIbQ53xn&{ zeeaKbu+wmVuBJ0fL};VO;gva4Z@b++dT+b$;;*OX)!HjXDkL9CG?IDVRCS@>JAlD+ zQS1B*8l^wHH>KZpSRLCT%(83y;r`Xey1 zX-?8|%`1w__l344{FYAL%D(8+zth|+g7){`pFj7t*(BBGS0`VqxJ=a`|JCzdDJ5mXkD`xyeE7Hf4C}H7GT-kP?00S! zUn_ZZe$Rz+^Rh>rZ}`QZ?%rveT5-Vc3@Svzn1d@mwsQVDx-U;=gzJO+&p)d{L&}ed8U`Xv|J#?B;5Znv+J*;+hQk1?0mFAL*VBkhGn0oy6-JKaMx1zQjG6;y{mf5_U;oq z=5xThx|sQrj_|6Pk9aRFozpT;dd|GS#?rYRr3)we=>9G}b5TZs??t0U<_qC&O_!~U zGQQlsHBY5))7x$LFK@Z{fb*irqcd5KS-Oigk1de?SKU{eXzkPVXS#ULw+C%|H~h%? zyypHt^*L(h7yH*`oQkgbvfbwmht@6W<9qtT&A|DOwYW41mi^vFA+p~KVD@_g%zkGe z*^iMCIRv?Bk?o93fZ5I%mhG&G$kpNoqQEEy=4w7rt`06ug5_yKneJ6~!Vb}x`@eqN zQCPSADgXLbaml@!`^sneB*$HN^6==AiD{RXP0df`5%u{K*ewvlx;MCTrEOz@gNwiD z@1I{@IoA5{PVTyEQJ|=JqI+{#F(zj3fhglyE1tE#+^tn`Q8c@* z>~(?bwvLR~r--eo0>#U8oAl zbd4Vj8s8#iyU(phUFHic-?zRmC#0C&@bqv0;zr7{U7LY9C=bfB7#Qdo=q%7$pwXt5 zQBqQ1rLUh{l%toJS)7`zmj*AU^-@yxGgFH7fN};QY#iEb!1A4)k&(s2z|Ft~#y4PU zvw)hBl3$*elb;CGfz6~MU@4!Rn4DTv0xIYAKn%1r3@!!cuJ4(^`8iPfliCE?!s!nE zG9S6pZ^Sh!d%j(@oM&Q5#XFYD51=`u78&@%dR=X2lBHEjR%|Gxfq zld(MM^Cp|32YnOo-8-zi=Z;LA*FuT!RzA)9k7if!PFvdZa>LW7C9kF&SjJTDRx`Kw zNpFL<;!AFc$4_@Smj#L~+|;okV_k9cjra{8R<2ao)2g&_y-=oAo#OZUHvjx9J<}(o z*nKLJxi*O}Zq>$kmbhR?g9$ltr;bl|-Ku4G>1SK|SG@!c=Q(i+MVGe9&Sh79EZwkm z_PsrBqM|EXvr6uS@Y%gx!XY?sYiv*Z!4~nHT;H^*$E!}u96Zz4qxm$qFj`}+)3Qdx Ss}t|%#;}DMPmB>*G!+0m + + + + + + + + + + + + + + + + + + + + diff --git a/settings.gradle b/settings.gradle index 54d1250e8..322be4211 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,6 +17,7 @@ include ':ids-route-manager' include ':ids-settings' include ':ids-token-manager' include ':ids-webconsole' +include ':idscp2' include ':javax-xml-bind-patch' include ':jnr-unixsocket-wrapper' include ':karaf-assembly' From 5cc8ac9b6fff7c307454054c2d996fdf13ccf136 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Wed, 20 Nov 2019 17:38:17 +0100 Subject: [PATCH 023/237] WIP idscp2 TLS server and client --- .../aisec/ids/idscp2/AttestationConfig.java | 15 ++ .../idscp2/Client/ClientConfiguration.java | 12 ++ .../ids/idscp2/Client/IDSCPv2Client.java | 47 +++++++ .../aisec/ids/idscp2/Client/TLSClient.java | 68 +++++++++ .../de/fhg/aisec/ids/idscp2/Constants.java | 23 ++++ .../ids/idscp2/IDSCPv2Configuration.java | 24 ++++ .../aisec/ids/idscp2/IDSCPv2Exception.java | 11 ++ .../ids/idscp2/Server/IDSCPv2Server.java | 59 ++++++++ .../ids/idscp2/Server/SSLServerThread.java | 31 +++++ .../idscp2/Server/ServerConfiguration.java | 13 ++ .../aisec/ids/idscp2/Server/ServerThread.java | 12 ++ .../aisec/ids/idscp2/Server/TLSServer.java | 129 ++++++++++++++++++ 12 files changed, 444 insertions(+) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java new file mode 100644 index 000000000..bffae6d66 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java @@ -0,0 +1,15 @@ +package de.fhg.aisec.ids.idscp2; + +/** + * Attestation configuration class, containing attestation suite for supported / expected attestation types + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class AttestationConfig { + + public AttestationConfig(){ + + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java new file mode 100644 index 000000000..4ffd490dd --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.Client; + +import de.fhg.aisec.ids.idscp2.IDSCPv2Configuration; + +/** + * IDSCPv2 Client Configuration. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class ClientConfiguration extends IDSCPv2Configuration { + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java new file mode 100644 index 000000000..eec54bb67 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java @@ -0,0 +1,47 @@ +package de.fhg.aisec.ids.idscp2.Client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.Socket; + +/** + * An abstract client implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public abstract class IDSCPv2Client { + private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Client.class); + + protected ClientConfiguration clientConfiguration = null; + protected Socket clientSocket = null; + + protected boolean connect(){ + if (clientSocket == null || clientSocket.isClosed()){ + LOG.error("Client socket is not available"); + return false; + } + + try { + clientSocket.connect(null, clientConfiguration.getServerPort()); + } catch (IOException e) { + LOG.error("Connecting client to server failed"); + e.printStackTrace(); + disconnect(); + return false; + } + return true; + } + + public void disconnect() { + if (clientSocket != null && !clientSocket.isClosed()){ + try { + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java new file mode 100644 index 000000000..fb657ced1 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -0,0 +1,68 @@ +package de.fhg.aisec.ids.idscp2.Client; + +import de.fhg.aisec.ids.idscp2.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +/** + * A TLS client implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class TLSClient extends IDSCPv2Client { + private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); + + public TLSClient(ClientConfiguration clientConfiguration){ + this.clientConfiguration = clientConfiguration; + + /* init TLS Client */ + try { + //create and load KeyManager and TrustManager + TrustManager[] myTrustManager = null; + KeyManager[] myKeyManager = null; + + SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + + SSLSocketFactory socketFactory = sslContext.getSocketFactory(); + + //create server socket + clientSocket = socketFactory.createSocket(); + + //toDo set sslParameters + SSLParameters sslParameters = ((SSLSocket)clientSocket).getSSLParameters(); + + + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ + LOG.error("Init TLS Client failed"); + e.printStackTrace(); + } + } + + @Override + public boolean connect() { + SSLSocket sslSocket = (SSLSocket) clientSocket; + if (super.connect()){ + try{ + sslSocket.startHandshake(); + } catch (IOException e){ + LOG.error("Starting TLS handshake failed"); + e.printStackTrace(); + disconnect(); + return false; + } + return true; + } + return false; + } + + public SSLSession getSslSession() { + return ((SSLSocket)clientSocket).getSession(); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java new file mode 100644 index 000000000..53773f37d --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java @@ -0,0 +1,23 @@ +package de.fhg.aisec.ids.idscp2; + +/** + * Global IDSCPv2 protocol constants + * + * @author Leon Beckmann(leon.beckmann@aisec.fraunhofer.de) + */ + +public final class Constants { + + //IDSCPv2 message types + public static final int ATTESTATION_REQUEST_MSG = 0; + public static final int ATTESTATION_RESPONSE_MSG = 1; + public static final int METADATA_REQUEST_MSG = 2; + public static final int METADATA_RESPONSE_MSG = 3; + public static final int PAYLOAD_MSG = 4; + + //socket instances + public static final String TLS_INSTANCE = "TLSv1.2"; + + + private Constants(){}; +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java new file mode 100644 index 000000000..5d16266ac --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java @@ -0,0 +1,24 @@ +package de.fhg.aisec.ids.idscp2; + +public abstract class IDSCPv2Configuration { + public static final int DEFAULT_SERVER_PORT = 8080; + + private int serverPort = DEFAULT_SERVER_PORT; + + private AttestationConfig supportedAttestation = null; + private AttestationConfig expectedAttestation = null; + + + + public AttestationConfig getExpectedAttestation() { + return expectedAttestation; + } + + public AttestationConfig getSupportedAttestation() { + return supportedAttestation; + } + + public int getServerPort() { + return serverPort; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java new file mode 100644 index 000000000..315182e33 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java @@ -0,0 +1,11 @@ +package de.fhg.aisec.ids.idscp2; + +public class IDSCPv2Exception extends RuntimeException{ + public IDSCPv2Exception(String message) { + super(message); + } + + public IDSCPv2Exception(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java new file mode 100644 index 000000000..276f3514e --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java @@ -0,0 +1,59 @@ +package de.fhg.aisec.ids.idscp2.Server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.ArrayList; + +/** + * An abstract server implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public abstract class IDSCPv2Server { + private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); + + protected ArrayList servers = new ArrayList<>(); + + protected ServerConfiguration serverConfiguration = null; + protected volatile boolean isRunning = false; + protected ServerSocket serverSocket = null; + + public IDSCPv2Server(){ + + } + + protected boolean start(){ + return (isRunning = true); + } + + public void stop(){ + isRunning = false; + terminateRunningThreads(); + } + + public void close(){ + if (serverSocket != null && !serverSocket.isClosed()){ + try { + serverSocket.close(); + } catch (IOException e) { + LOG.error("Could not close server socket"); + e.printStackTrace(); + } + } + terminateRunningThreads(); + } + + private void terminateRunningThreads(){ + for (ServerThread thread : servers){ + thread.safeStop(); + } + servers.clear(); + } + + public boolean isRunning(){ + return isRunning; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java new file mode 100644 index 000000000..e53b9e9ca --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java @@ -0,0 +1,31 @@ +package de.fhg.aisec.ids.idscp2.Server; + +import javax.net.ssl.SSLSocket; + +/** + * A TLS server thread implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class SSLServerThread extends Thread implements ServerThread{ + + private SSLSocket sslSocket = null; + private volatile boolean running = true; + + SSLServerThread(SSLSocket sslSocket){ + this.sslSocket = sslSocket; + } + + @Override + public void run(){ + while (running){ + //do something + + } + } + + public void safeStop(){ + running = false; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java new file mode 100644 index 000000000..cacdab133 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java @@ -0,0 +1,13 @@ +package de.fhg.aisec.ids.idscp2.Server; + +import de.fhg.aisec.ids.idscp2.IDSCPv2Configuration; + +/** + * IDSCPv2 Server Configuration + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class ServerConfiguration extends IDSCPv2Configuration { + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java new file mode 100644 index 000000000..64fe4de77 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.Server; + +/** + * A server thread interface for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public interface ServerThread { + + void safeStop(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java new file mode 100644 index 000000000..cde0f5086 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -0,0 +1,129 @@ +package de.fhg.aisec.ids.idscp2.Server; + +import de.fhg.aisec.ids.idscp2.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +/** + * A TLS server implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class TLSServer extends IDSCPv2Server { + private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); + + public TLSServer(ServerConfiguration serverConfiguration){ + this.serverConfiguration = serverConfiguration; + + /* init server for TCP/TLS communication */ + try { + //toDo create and load KeyManager and TrustManager + TrustManager[] myTrustManager = null; + KeyManager[] myKeyManager = null; + + SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + + SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); + + //create server socket + serverSocket = socketFactory.createServerSocket(serverConfiguration.getServerPort()); + + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ + LOG.error("Init SSL server socket failed"); + e.printStackTrace(); + } + } + + @Override + public boolean start() { + if (serverSocket == null || serverSocket.isClosed()){ + LOG.error("SSL Server socket is not available"); + return false; + } + + //run server + super.start(); + + try { + while(isRunning){ + SSLSocket sslSocket = (SSLSocket) serverSocket.accept(); + + //set SSL Parameters + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite + sslParameters.setNeedClientAuth(true); //client must authenticate + + //start handshake + sslSocket.startHandshake(); + + //start new thread + SSLServerThread server = new SSLServerThread(sslSocket); + //server.setName(); + servers.add(server); + server.start(); + } + + } catch (IOException e) { + LOG.error("SSL Server failed"); + e.printStackTrace(); + return false; + } + + return true; + } + + + /*InputStream jksKeyStoreInputStream = + Files.newInputStream(targetDirectory.resolve(keyStoreName)); + InputStream jksTrustStoreInputStream = + Files.newInputStream(targetDirectory.resolve(trustStoreName)); + + KeyStore keystore = KeyStore.getInstance("JKS"); + KeyStore trustManagerKeyStore = KeyStore.getInstance("JKS"); + + LOG.info("Loading key store: " + keyStoreName); + LOG.info("Loading trus store: " + trustStoreName); + keystore.load(jksKeyStoreInputStream, keyStorePassword.toCharArray()); + trustManagerKeyStore.load(jksTrustStoreInputStream, keyStorePassword.toCharArray()); + java.security.cert.Certificate[] certs = trustManagerKeyStore.getCertificateChain("ca"); + LOG.info("Cert chain: " + Arrays.toString(certs)); + + LOG.info("LOADED CA CERT: " + trustManagerKeyStore.getCertificate("ca")); + jksKeyStoreInputStream.close(); + jksTrustStoreInputStream.close(); + + * // get private key + Key privKey = (PrivateKey) keystore.getKey(keystoreAliasName, keyStorePassword.toCharArray()); + // Get certificate of public key + X509Certificate cert = (X509Certificate) keystore.getCertificate(keystoreAliasName); + + TrustManager[] trustManagers; + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustManagerKeyStore); + trustManagers = trustManagerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException( + "Unexpected default trust managers:" + Arrays.toString(trustManagers)); + } + */ + + /* + * @Override +public void close() throws IOException { + try ( + Socket s = socket; + InputStream i = in; + OutputStream o = out; + ) { + sendMessage(Message.CLIENT_CLOSE); + } +}*/ +} From 29bbb20697312af88fc89ffb34a4010176aab4d4 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 21 Nov 2019 17:24:16 +0100 Subject: [PATCH 024/237] WIP TLS Client and Server, add TrustManager and KeyManager --- .../ids/idscp2/Client/IDSCPv2Client.java | 4 + .../aisec/ids/idscp2/Client/TLSClient.java | 23 +++- .../ids/idscp2/IDSCPv2Configuration.java | 21 ++++ .../ids/idscp2/Server/IDSCPv2Server.java | 4 +- .../aisec/ids/idscp2/Server/TLSServer.java | 89 ++++---------- .../aisec/ids/idscp2/TLSPreConfiguration.java | 114 ++++++++++++++++++ 6 files changed, 185 insertions(+), 70 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java index eec54bb67..ff2ef283d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java @@ -44,4 +44,8 @@ public void disconnect() { } } + public boolean isConnected(){ + return clientSocket != null && clientSocket.isConnected(); + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index fb657ced1..0ff467817 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -1,6 +1,7 @@ package de.fhg.aisec.ids.idscp2.Client; import de.fhg.aisec.ids.idscp2.Constants; +import de.fhg.aisec.ids.idscp2.TLSPreConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,9 +24,19 @@ public TLSClient(ClientConfiguration clientConfiguration){ /* init TLS Client */ try { - //create and load KeyManager and TrustManager - TrustManager[] myTrustManager = null; - KeyManager[] myKeyManager = null; + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + clientConfiguration.getTrustStorePath(), + clientConfiguration.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + clientConfiguration.getKeyStorePath(), + clientConfiguration.getKeyStorePassword() + ); SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); sslContext.init(myKeyManager, myTrustManager, null); @@ -35,8 +46,12 @@ public TLSClient(ClientConfiguration clientConfiguration){ //create server socket clientSocket = socketFactory.createSocket(); + SSLSocket sslSocket = (SSLSocket) clientSocket; + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(false); //use server priority order + sslParameters.setWantClientAuth(true); //toDo set sslParameters - SSLParameters sslParameters = ((SSLSocket)clientSocket).getSSLParameters(); + sslSocket.setSSLParameters(sslParameters); } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java index 5d16266ac..d4780f2e2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java @@ -4,6 +4,11 @@ public abstract class IDSCPv2Configuration { public static final int DEFAULT_SERVER_PORT = 8080; private int serverPort = DEFAULT_SERVER_PORT; + private String trustStorePath = null; + private String trustStorePassword = "password"; + private String keyStorePath = null; + private String keyStorePassword = "password"; + private AttestationConfig supportedAttestation = null; private AttestationConfig expectedAttestation = null; @@ -21,4 +26,20 @@ public AttestationConfig getSupportedAttestation() { public int getServerPort() { return serverPort; } + + public String getKeyStorePath() { + return keyStorePath; + } + + public String getKeyStorePassword() { + return keyStorePassword; + } + + public String getTrustStorePath() { + return trustStorePath; + } + + public String getTrustStorePassword() { + return trustStorePassword; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java index 276f3514e..1fd437238 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java @@ -21,8 +21,8 @@ public abstract class IDSCPv2Server { protected volatile boolean isRunning = false; protected ServerSocket serverSocket = null; - public IDSCPv2Server(){ - + public IDSCPv2Server(ServerConfiguration serverConfiguration){ + this.serverConfiguration = serverConfiguration; } protected boolean start(){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index cde0f5086..3fad1e4fb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -1,13 +1,13 @@ package de.fhg.aisec.ids.idscp2.Server; import de.fhg.aisec.ids.idscp2.Constants; +import de.fhg.aisec.ids.idscp2.TLSPreConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.io.IOException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; +import java.security.*; /** * A TLS server implementation for the IDSCPv2 protocol. @@ -19,22 +19,39 @@ public class TLSServer extends IDSCPv2Server { private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); public TLSServer(ServerConfiguration serverConfiguration){ - this.serverConfiguration = serverConfiguration; + super(serverConfiguration); /* init server for TCP/TLS communication */ try { - //toDo create and load KeyManager and TrustManager - TrustManager[] myTrustManager = null; - KeyManager[] myKeyManager = null; - + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + serverConfiguration.getTrustStorePath(), + serverConfiguration.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + serverConfiguration.getKeyStorePath(), + serverConfiguration.getKeyStorePassword() + ); + + // create tls context based on keyManager and trustManager SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); sslContext.init(myKeyManager, myTrustManager, null); - SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); //create server socket serverSocket = socketFactory.createServerSocket(serverConfiguration.getServerPort()); + SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; + SSLParameters sslParameters = sslServerSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite + sslParameters.setNeedClientAuth(true); //client must authenticate + //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... + sslServerSocket.setSSLParameters(sslParameters); + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ LOG.error("Init SSL server socket failed"); e.printStackTrace(); @@ -55,14 +72,6 @@ public boolean start() { while(isRunning){ SSLSocket sslSocket = (SSLSocket) serverSocket.accept(); - //set SSL Parameters - SSLParameters sslParameters = sslSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite - sslParameters.setNeedClientAuth(true); //client must authenticate - - //start handshake - sslSocket.startHandshake(); - //start new thread SSLServerThread server = new SSLServerThread(sslSocket); //server.setName(); @@ -78,52 +87,4 @@ public boolean start() { return true; } - - - /*InputStream jksKeyStoreInputStream = - Files.newInputStream(targetDirectory.resolve(keyStoreName)); - InputStream jksTrustStoreInputStream = - Files.newInputStream(targetDirectory.resolve(trustStoreName)); - - KeyStore keystore = KeyStore.getInstance("JKS"); - KeyStore trustManagerKeyStore = KeyStore.getInstance("JKS"); - - LOG.info("Loading key store: " + keyStoreName); - LOG.info("Loading trus store: " + trustStoreName); - keystore.load(jksKeyStoreInputStream, keyStorePassword.toCharArray()); - trustManagerKeyStore.load(jksTrustStoreInputStream, keyStorePassword.toCharArray()); - java.security.cert.Certificate[] certs = trustManagerKeyStore.getCertificateChain("ca"); - LOG.info("Cert chain: " + Arrays.toString(certs)); - - LOG.info("LOADED CA CERT: " + trustManagerKeyStore.getCertificate("ca")); - jksKeyStoreInputStream.close(); - jksTrustStoreInputStream.close(); - - * // get private key - Key privKey = (PrivateKey) keystore.getKey(keystoreAliasName, keyStorePassword.toCharArray()); - // Get certificate of public key - X509Certificate cert = (X509Certificate) keystore.getCertificate(keystoreAliasName); - - TrustManager[] trustManagers; - TrustManagerFactory trustManagerFactory = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trustManagerKeyStore); - trustManagers = trustManagerFactory.getTrustManagers(); - if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { - throw new IllegalStateException( - "Unexpected default trust managers:" + Arrays.toString(trustManagers)); - } - */ - - /* - * @Override -public void close() throws IOException { - try ( - Socket s = socket; - InputStream i = in; - OutputStream o = out; - ) { - sendMessage(Message.CLIENT_CLOSE); - } -}*/ } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java new file mode 100644 index 000000000..b13397cb6 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java @@ -0,0 +1,114 @@ +package de.fhg.aisec.ids.idscp2; + +import javax.net.ssl.*; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.*; +import java.security.cert.*; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * A class for creating pre-configured TrustManagers and KeyManagers for TLS Server and TLS Client + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class TLSPreConfiguration { + + public static TrustManager[] getX509ExtTrustManager( + String trustStorePath, + String trustStorePassword + ) { + try ( + InputStream jksTrustStoreIn = Files.newInputStream(Paths.get(trustStorePath)) + ) { + /* create TrustManager */ + TrustManager[] myTrustManager; + KeyStore trustStore = KeyStore.getInstance("JKS"); + trustStore.load(jksTrustStoreIn, trustStorePassword.toCharArray()); + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE + + /* filterTrustAnchors for validation + ManagerFactoryParameters trustParams = + new CertPathTrustManagerParameters(filterTrustAnchors(trustStore)); + trustManagerFactory.init(trustParams);*/ + + trustManagerFactory.init(trustStore); + myTrustManager = trustManagerFactory.getTrustManagers(); + + + /* set up TrustManager config */ + //allow only X509 Authentication + if (myTrustManager.length == 1 && myTrustManager[0] instanceof X509ExtendedTrustManager) { + //toDo hostname verification and algorithm constraints + + return myTrustManager; + } else { + throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(myTrustManager)); + } + } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException e) { + e.printStackTrace(); + } + return null; + } + + public static KeyManager[] getX509ExtKeyManager( + String keyStorePath, + String keyStorePassword + ) { + try ( + InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)); + ) { + /* create KeyManager for remote authentication */ + KeyManager[] myKeyManager; + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(jksKeyStoreIn, keyStorePassword.toCharArray()); + KeyManagerFactory keyManagerFactory = + KeyManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE + keyManagerFactory.init(keystore, keyStorePassword.toCharArray()); + myKeyManager = keyManagerFactory.getKeyManagers(); + + /* set up keyManager config */ + //allow only X509 Authentication + if (myKeyManager.length == 1 && myKeyManager[0] instanceof X509ExtendedKeyManager) { + //toDo connection specific key selection via KeyAlias + + return myKeyManager; + } else { + throw new IllegalStateException( + "Unexpected default key managers:" + Arrays.toString(myKeyManager)); + } + + } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException + | CertificateException e) { + e.printStackTrace(); + } + return null; //some exception was raised + } + + private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore) + throws KeyStoreException, InvalidAlgorithmParameterException { + PKIXParameters params = new PKIXParameters(keyStore); + + // Obtain CA root certificates + Set myTrustAnchors = params.getTrustAnchors(); + + // Create new set of CA certificates that are still valid for specified date + Set validTrustAnchors = + myTrustAnchors.stream().filter( + ta -> { + try { + ta.getTrustedCert().checkValidity(/* toDo expiration date*/); + } catch (CertificateException e) { + return false; + } + return true; }).collect(Collectors.toSet()); + + // Create PKIXBuilderParameters parameters + return new PKIXBuilderParameters(validTrustAnchors, new X509CertSelector()); + } +} \ No newline at end of file From 45a8c077b27e8de7f9828dea514863c6db5b4c6e Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 25 Nov 2019 18:19:18 +0100 Subject: [PATCH 025/237] WIP TLS Communication, input / output, handshakeCompletedListener --- .../idscp2/Client/ClientConfiguration.java | 5 + .../ids/idscp2/Client/IDSCPv2Client.java | 61 ++++++++- .../aisec/ids/idscp2/Client/TLSClient.java | 49 +++++-- .../de/fhg/aisec/ids/idscp2/Constants.java | 5 + .../ids/idscp2/DataAvailableListener.java | 13 ++ .../fhg/aisec/ids/idscp2/InputListener.java | 15 +++ .../aisec/ids/idscp2/InputListenerThread.java | 60 +++++++++ .../ids/idscp2/Server/SSLServerThread.java | 31 ----- .../aisec/ids/idscp2/Server/ServerThread.java | 3 +- .../aisec/ids/idscp2/Server/TLSServer.java | 11 +- .../ids/idscp2/Server/TLSServerThread.java | 122 ++++++++++++++++++ .../aisec/ids/idscp2/TLSPreConfiguration.java | 1 + 12 files changed, 323 insertions(+), 53 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java index 4ffd490dd..264b2f2c2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java @@ -9,4 +9,9 @@ */ public class ClientConfiguration extends IDSCPv2Configuration { + private String hostname = "localhost"; + + public String getHostname() { + return hostname; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java index ff2ef283d..3bbc3d08f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java @@ -1,30 +1,54 @@ package de.fhg.aisec.ids.idscp2.Client; +import de.fhg.aisec.ids.idscp2.Constants; +import de.fhg.aisec.ids.idscp2.DataAvailableListener; +import de.fhg.aisec.ids.idscp2.InputListener; +import de.fhg.aisec.ids.idscp2.InputListenerThread; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; import java.net.Socket; +import java.util.Arrays; /** * An abstract client implementation for the IDSCPv2 protocol. * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public abstract class IDSCPv2Client { +public abstract class IDSCPv2Client implements DataAvailableListener { private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Client.class); protected ClientConfiguration clientConfiguration = null; protected Socket clientSocket = null; + protected OutputStream out = null; + protected InputStream in = null; + protected InputListenerThread inputListenerThread = null; - protected boolean connect(){ + public IDSCPv2Client(){ + + } + + public boolean connect(){ if (clientSocket == null || clientSocket.isClosed()){ LOG.error("Client socket is not available"); return false; } try { - clientSocket.connect(null, clientConfiguration.getServerPort()); + clientSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), + clientConfiguration.getServerPort())); + out = clientSocket.getOutputStream(); + in = clientSocket.getInputStream(); + + //start receiving listener + inputListenerThread = new InputListenerThread(in); + inputListenerThread.register(this); + inputListenerThread.start(); + } catch (IOException e) { LOG.error("Connecting client to server failed"); e.printStackTrace(); @@ -37,6 +61,10 @@ protected boolean connect(){ public void disconnect() { if (clientSocket != null && !clientSocket.isClosed()){ try { + send(Constants.CLIENT_GOODBYE); + inputListenerThread.safeStop(); + in.close(); + out.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); @@ -44,6 +72,33 @@ public void disconnect() { } } + public void send(byte[] data){ + if (!isConnected()){ + LOG.error("Client cannot send data because socket is not connected"); + } else { + try { + out.write(data); + out.flush(); + } catch (IOException e){ + LOG.error("Client cannot send data"); + e.printStackTrace(); + } + } + } + + public void send(String data){ + send(data.getBytes()); + } + + /* this is called by a listener thread when data were received*/ + public void onMessage(byte[] data){ + if (Arrays.toString(data).equals(Constants.END_OF_STREAM)){ + //End of stream, connection is not available anymore + } + //toDo do something with the received data + System.out.println("New data received: " + Arrays.toString(data)); + } + public boolean isConnected(){ return clientSocket != null && clientSocket.isConnected(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index 0ff467817..d15f4f664 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -1,12 +1,14 @@ package de.fhg.aisec.ids.idscp2.Client; import de.fhg.aisec.ids.idscp2.Constants; +import de.fhg.aisec.ids.idscp2.InputListenerThread; import de.fhg.aisec.ids.idscp2.TLSPreConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.io.IOException; +import java.net.InetSocketAddress; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -16,7 +18,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TLSClient extends IDSCPv2Client { +public class TLSClient extends IDSCPv2Client implements HandshakeCompletedListener{ private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); public TLSClient(ClientConfiguration clientConfiguration){ @@ -50,10 +52,10 @@ public TLSClient(ClientConfiguration clientConfiguration){ SSLParameters sslParameters = sslSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(false); //use server priority order sslParameters.setWantClientAuth(true); - //toDo set sslParameters + sslParameters.setProtocols(new String[] {Constants.TLS_INSTANCE}); //only TLSv1.2 + //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever sslSocket.setSSLParameters(sslParameters); - } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ LOG.error("Init TLS Client failed"); e.printStackTrace(); @@ -63,21 +65,40 @@ public TLSClient(ClientConfiguration clientConfiguration){ @Override public boolean connect() { SSLSocket sslSocket = (SSLSocket) clientSocket; - if (super.connect()){ - try{ - sslSocket.startHandshake(); - } catch (IOException e){ - LOG.error("Starting TLS handshake failed"); - e.printStackTrace(); - disconnect(); - return false; - } - return true; + if (sslSocket == null || sslSocket.isClosed()){ + System.out.println("Client socket is not available"); + return false; } - return false; + + try { + sslSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), + clientConfiguration.getServerPort())); + out = clientSocket.getOutputStream(); + in = clientSocket.getInputStream(); + + //start tls handshake + sslSocket.addHandshakeCompletedListener(this); + sslSocket.startHandshake(); + + + } catch (IOException e) { + System.out.println("Connecting TLS client to server failed"); + e.printStackTrace(); + disconnect(); + return false; + } + return true; } public SSLSession getSslSession() { return ((SSLSocket)clientSocket).getSession(); } + + @Override + public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { + //start receiving listener for IDSCPv2 communication + inputListenerThread = new InputListenerThread(in); + inputListenerThread.register(this); + inputListenerThread.start(); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java index 53773f37d..f8c33651a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java @@ -18,6 +18,11 @@ public final class Constants { //socket instances public static final String TLS_INSTANCE = "TLSv1.2"; + //Standard Messages + public static final String CLIENT_GOODBYE = "Client is disconnecting"; + public static final String SERVER_GOODBYE = "Server is disconnecting"; + public static final String END_OF_STREAM = "End of stream"; + private Constants(){}; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java new file mode 100644 index 000000000..61bc146ab --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java @@ -0,0 +1,13 @@ +package de.fhg.aisec.ids.idscp2; + +/** + * A Interface for DataAvailableListeners + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public interface DataAvailableListener { + + void onMessage(byte[] bytes); + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java new file mode 100644 index 000000000..f4f8dc78f --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java @@ -0,0 +1,15 @@ +package de.fhg.aisec.ids.idscp2; + +/** + * A event source interface for DataAvailableListener pattern + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface InputListener { + + void register(DataAvailableListener listener); + + void unregister(DataAvailableListener listener); + + void safeStop(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java new file mode 100644 index 000000000..9d143f1f6 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java @@ -0,0 +1,60 @@ +package de.fhg.aisec.ids.idscp2; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +/** + * A simple Listener thread that listens to an input stream and notifies all listeners when data was received + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class InputListenerThread extends Thread implements InputListener{ + + private InputStream in; + private ArrayList listeners = new ArrayList<>(); + private volatile boolean running = true; + + public InputListenerThread(InputStream in){ + this.in = in; + } + + public void run(){ + byte[] buf = new byte[2048]; + while (running){ + try { + //toDo interrupt read when running is set to false + if (0 > in.read(buf,0, buf.length -1)) { + notifyListeners(Constants.END_OF_STREAM.getBytes()); + running = false; //terminate + } else { + notifyListeners(buf); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + listeners.clear(); + } + + @Override + public void register(DataAvailableListener listener) { + listeners.add(listener); + } + + @Override + public void unregister(DataAvailableListener listener) { + listeners.remove(listener); + } + + private void notifyListeners(byte[] bytes) { + for (DataAvailableListener listener : listeners){ + listener.onMessage(bytes); + } + } + + @Override + public void safeStop() { + this.running = false; + } +} \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java deleted file mode 100644 index e53b9e9ca..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/SSLServerThread.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -import javax.net.ssl.SSLSocket; - -/** - * A TLS server thread implementation for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public class SSLServerThread extends Thread implements ServerThread{ - - private SSLSocket sslSocket = null; - private volatile boolean running = true; - - SSLServerThread(SSLSocket sslSocket){ - this.sslSocket = sslSocket; - } - - @Override - public void run(){ - while (running){ - //do something - - } - } - - public void safeStop(){ - running = false; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java index 64fe4de77..342a60b13 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java @@ -7,6 +7,7 @@ */ public interface ServerThread { - + void send(byte[] bytes); void safeStop(); + boolean isConnected(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index 3fad1e4fb..827b5925a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -49,9 +49,11 @@ public TLSServer(ServerConfiguration serverConfiguration){ SSLParameters sslParameters = sslServerSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite sslParameters.setNeedClientAuth(true); //client must authenticate - //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... + sslParameters.setProtocols(new String[] {Constants.TLS_INSTANCE}); //only TLSv1.2 + //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever sslServerSocket.setSSLParameters(sslParameters); + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ LOG.error("Init SSL server socket failed"); e.printStackTrace(); @@ -72,10 +74,11 @@ public boolean start() { while(isRunning){ SSLSocket sslSocket = (SSLSocket) serverSocket.accept(); - //start new thread - SSLServerThread server = new SSLServerThread(sslSocket); - //server.setName(); + //start new server thread + TLSServerThread server = new TLSServerThread(sslSocket); + //toDo server.setName(); hashmap servers.add(server); + sslSocket.addHandshakeCompletedListener(server); server.start(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java new file mode 100644 index 000000000..172a1ca2d --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java @@ -0,0 +1,122 @@ +package de.fhg.aisec.ids.idscp2.Server; + +import de.fhg.aisec.ids.idscp2.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.HandshakeCompletedEvent; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; + +/** + * A TLS server thread implementation for the IDSCPv2 protocol. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class TLSServerThread extends Thread implements ServerThread, HandshakeCompletedListener { + private static final Logger LOG = LoggerFactory.getLogger(TLSServerThread.class); + + private SSLSocket sslSocket; + private volatile boolean running = true; + private InputStream in; + private OutputStream out; + private boolean tlsHandshakeCompleted = false; + + TLSServerThread(SSLSocket sslSocket){ + this.sslSocket = sslSocket; + try { + in = sslSocket.getInputStream(); + out = sslSocket.getOutputStream(); + } catch (IOException e){ + LOG.error(e.getMessage()); + running = false; + } + } + + @Override + public void run(){ + //wait for new data while running + byte[] buf = new byte[2048]; + + //wait until tls handshake is completed + //toDo avoid busy waiting + while(!tlsHandshakeCompleted){ + try { + sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + while (running){ + try { + //toDo interrupt read when running is set to false + if (0 > in.read(buf, 0, buf.length - 1)) { + onMessage(Constants.END_OF_STREAM.getBytes()); + } else { + onMessage(buf); + } + } catch (IOException e){ + e.printStackTrace(); + } + } + try { + send(Constants.SERVER_GOODBYE); + out.close(); + in.close(); + sslSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void send(byte[] data) { + if (!isConnected()){ + LOG.error("Server cannot send data because socket is not connected"); + } else { + try { + out.write(data); + out.flush(); + } catch (IOException e){ + LOG.error("Server cannot send data"); + e.printStackTrace(); + } + } + } + + public void send(String data){ + send(data.getBytes()); + } + + public void onMessage(byte[] data) { + if (Arrays.toString(data).equals(Constants.END_OF_STREAM) || + Arrays.toString(data).equals(Constants.CLIENT_GOODBYE)){ + //End of stream or client goodbye, connection is no longer available + running = false; //terminate server + } else { + //toDo do something with the received data + System.out.println("New data received: " + Arrays.toString(data)); + } + } + + public void safeStop(){ + running = false; + } + + @Override + public boolean isConnected() { + return (sslSocket != null && sslSocket.isConnected()); + } + + + @Override + public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { + tlsHandshakeCompleted = true; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java index b13397cb6..258735608 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java @@ -77,6 +77,7 @@ public static KeyManager[] getX509ExtKeyManager( if (myKeyManager.length == 1 && myKeyManager[0] instanceof X509ExtendedKeyManager) { //toDo connection specific key selection via KeyAlias + return myKeyManager; } else { throw new IllegalStateException( From 614821605acbeddb79586bf52eb709c71287c0ec Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 28 Nov 2019 18:12:23 +0100 Subject: [PATCH 026/237] WIP TLS Communication: add saveStop implementation for blocking server IO calls, secure cipher suite, catch SSL Handshake Exceptions --- .../ids/idscp2/Client/IDSCPv2Client.java | 2 + .../aisec/ids/idscp2/Client/TLSClient.java | 12 ++-- .../de/fhg/aisec/ids/idscp2/Constants.java | 55 ++++++++++++++++++- .../aisec/ids/idscp2/InputListenerThread.java | 8 ++- .../aisec/ids/idscp2/Server/TLSServer.java | 39 ++++++++----- .../ids/idscp2/Server/TLSServerThread.java | 9 ++- .../aisec/ids/idscp2/TLSPreConfiguration.java | 2 +- 7 files changed, 100 insertions(+), 27 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java index 3bbc3d08f..6c5dc2cb2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java @@ -44,6 +44,8 @@ public boolean connect(){ out = clientSocket.getOutputStream(); in = clientSocket.getInputStream(); + //set clientSocket timeout to allow safeStop() + clientSocket.setSoTimeout(5000); //start receiving listener inputListenerThread = new InputListenerThread(in); inputListenerThread.register(this); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index d15f4f664..df89f8171 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -8,6 +8,7 @@ import javax.net.ssl.*; import java.io.IOException; +import java.net.ConnectException; import java.net.InetSocketAddress; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -51,8 +52,9 @@ public TLSClient(ClientConfiguration clientConfiguration){ SSLSocket sslSocket = (SSLSocket) clientSocket; SSLParameters sslParameters = sslSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(false); //use server priority order - sslParameters.setWantClientAuth(true); - sslParameters.setProtocols(new String[] {Constants.TLS_INSTANCE}); //only TLSv1.2 + sslParameters.setNeedClientAuth(true); + sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 + sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever sslSocket.setSSLParameters(sslParameters); @@ -79,11 +81,9 @@ public boolean connect() { //start tls handshake sslSocket.addHandshakeCompletedListener(this); sslSocket.startHandshake(); - - } catch (IOException e) { - System.out.println("Connecting TLS client to server failed"); - e.printStackTrace(); + LOG.error("Connecting TLS client to server failed"); + //e.printStackTrace(); disconnect(); return false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java index f8c33651a..207ffdc0c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java @@ -15,14 +15,65 @@ public final class Constants { public static final int METADATA_RESPONSE_MSG = 3; public static final int PAYLOAD_MSG = 4; - //socket instances - public static final String TLS_INSTANCE = "TLSv1.2"; //Standard Messages public static final String CLIENT_GOODBYE = "Client is disconnecting"; public static final String SERVER_GOODBYE = "Server is disconnecting"; public static final String END_OF_STREAM = "End of stream"; + /* TLS specific settings */ + + //socket instances + public static final String TLS_INSTANCE = "TLSv1.2"; + + //enabled protocols + public static final String[] TLS_ENABLED_PROTOCOLS = {TLS_INSTANCE}; + public static final String[] TLS_ENABLED_CIPHER = { + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + /*"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ + }; + private Constants(){}; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java index 9d143f1f6..e4bdfe6b6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.InputStream; +import java.net.SocketTimeoutException; import java.util.ArrayList; /** @@ -23,13 +24,16 @@ public void run(){ byte[] buf = new byte[2048]; while (running){ try { - //toDo interrupt read when running is set to false - if (0 > in.read(buf,0, buf.length -1)) { + if (0 > in.read(buf, 0, buf.length - 1)) { notifyListeners(Constants.END_OF_STREAM.getBytes()); running = false; //terminate } else { notifyListeners(buf); } + } catch (SocketTimeoutException e){ + //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye + //alternative: close socket / InputStream and catch exception + //continue; } catch (IOException e) { e.printStackTrace(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index 827b5925a..3eb4c4d36 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -7,6 +7,7 @@ import javax.net.ssl.*; import java.io.IOException; +import java.net.SocketTimeoutException; import java.security.*; /** @@ -44,12 +45,14 @@ public TLSServer(ServerConfiguration serverConfiguration){ //create server socket serverSocket = socketFactory.createServerSocket(serverConfiguration.getServerPort()); + //set timeout for serverSocket.accept() to allow safeStop() + serverSocket.setSoTimeout(5000); SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; SSLParameters sslParameters = sslServerSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite sslParameters.setNeedClientAuth(true); //client must authenticate - sslParameters.setProtocols(new String[] {Constants.TLS_INSTANCE}); //only TLSv1.2 + sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever sslServerSocket.setSSLParameters(sslParameters); @@ -70,22 +73,28 @@ public boolean start() { //run server super.start(); - try { - while(isRunning){ - SSLSocket sslSocket = (SSLSocket) serverSocket.accept(); - - //start new server thread - TLSServerThread server = new TLSServerThread(sslSocket); - //toDo server.setName(); hashmap - servers.add(server); - sslSocket.addHandshakeCompletedListener(server); - server.start(); + SSLSocket sslSocket; + while(isRunning){ + try { + sslSocket = (SSLSocket) serverSocket.accept(); + } catch (SocketTimeoutException e){ + //timeout on serverSocket blocking functions was reached + //in this way we can catch safeStop() function, that makes isRunning false + //without closing the serverSocket, so we can stop and restart the server + //alternative: close serverSocket. But then we cannot reuse it + continue; + } catch (IOException e) { + System.out.println("SSL Server failed"); + e.printStackTrace(); + return false; } - } catch (IOException e) { - LOG.error("SSL Server failed"); - e.printStackTrace(); - return false; + //start new server thread + TLSServerThread server = new TLSServerThread(sslSocket); + //toDo server.setName() + hashmap + servers.add(server); + sslSocket.addHandshakeCompletedListener(server); + server.start(); } return true; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java index 172a1ca2d..667a7e2c9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java @@ -10,6 +10,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.SocketException; +import java.net.SocketTimeoutException; import java.util.Arrays; /** @@ -30,6 +32,8 @@ public class TLSServerThread extends Thread implements ServerThread, HandshakeCo TLSServerThread(SSLSocket sslSocket){ this.sslSocket = sslSocket; try { + //set timout for blocking read + sslSocket.setSoTimeout(5000); in = sslSocket.getInputStream(); out = sslSocket.getOutputStream(); } catch (IOException e){ @@ -55,12 +59,15 @@ public void run(){ while (running){ try { - //toDo interrupt read when running is set to false if (0 > in.read(buf, 0, buf.length - 1)) { onMessage(Constants.END_OF_STREAM.getBytes()); } else { onMessage(buf); } + } catch (SocketTimeoutException e){ + //timeout catches safeStop() call and allows to send server_goodbye + //alternative: close sslSocket and catch SocketException + //continue } catch (IOException e){ e.printStackTrace(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java index 258735608..dfc92f2b3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java @@ -36,8 +36,8 @@ public static TrustManager[] getX509ExtTrustManager( ManagerFactoryParameters trustParams = new CertPathTrustManagerParameters(filterTrustAnchors(trustStore)); trustManagerFactory.init(trustParams);*/ - trustManagerFactory.init(trustStore); + myTrustManager = trustManagerFactory.getTrustManagers(); From 287712328c049dcc80b19905cae5ca42d20af819 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 2 Dec 2019 18:23:57 +0100 Subject: [PATCH 027/237] WIP: TLS communication, working Keystores, fixing client and server shutdown, fixing message format --- .../ids/idscp2/Client/IDSCPv2Client.java | 37 +++++++++----- .../aisec/ids/idscp2/Client/TLSClient.java | 26 +++++++--- .../ids/idscp2/DataAvailableListener.java | 2 +- .../aisec/ids/idscp2/InputListenerThread.java | 14 +++--- .../ids/idscp2/Server/IDSCPv2Server.java | 3 ++ .../aisec/ids/idscp2/Server/TLSServer.java | 6 ++- .../ids/idscp2/Server/TLSServerThread.java | 46 ++++++++++-------- .../aisec/ids/idscp2/TLSPreConfiguration.java | 2 - .../jsse/aisecconnector1-keystore.jks | Bin 0 -> 2527 bytes .../jsse/aisecconnector2-keystore.jks | Bin 0 -> 2525 bytes .../test/resources/jsse/client-keystore.jks | Bin 2495 -> 0 bytes .../test/resources/jsse/client-truststore.jks | Bin 1954 -> 0 bytes .../resources/jsse/client-truststore_new.jks | Bin 0 -> 1974 bytes .../test/resources/jsse/server-keystore.jks | Bin 4494 -> 0 bytes .../test/resources/jsse/server-truststore.jks | Bin 1954 -> 0 bytes 15 files changed, 86 insertions(+), 50 deletions(-) create mode 100644 idscp2/src/test/resources/jsse/aisecconnector1-keystore.jks create mode 100644 idscp2/src/test/resources/jsse/aisecconnector2-keystore.jks delete mode 100644 idscp2/src/test/resources/jsse/client-keystore.jks delete mode 100644 idscp2/src/test/resources/jsse/client-truststore.jks create mode 100644 idscp2/src/test/resources/jsse/client-truststore_new.jks delete mode 100644 idscp2/src/test/resources/jsse/server-keystore.jks delete mode 100644 idscp2/src/test/resources/jsse/server-truststore.jks diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java index 6c5dc2cb2..4ee6b8d10 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java @@ -2,7 +2,6 @@ import de.fhg.aisec.ids.idscp2.Constants; import de.fhg.aisec.ids.idscp2.DataAvailableListener; -import de.fhg.aisec.ids.idscp2.InputListener; import de.fhg.aisec.ids.idscp2.InputListenerThread; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,7 +11,7 @@ import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; -import java.util.Arrays; +import java.nio.charset.StandardCharsets; /** * An abstract client implementation for the IDSCPv2 protocol. @@ -41,35 +40,45 @@ public boolean connect(){ try { clientSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), clientConfiguration.getServerPort())); + LOG.info("Client is connected to server " + clientConfiguration.getHostname() + + ":" + clientConfiguration.getServerPort()); out = clientSocket.getOutputStream(); in = clientSocket.getInputStream(); //set clientSocket timeout to allow safeStop() clientSocket.setSoTimeout(5000); + //start receiving listener inputListenerThread = new InputListenerThread(in); inputListenerThread.register(this); inputListenerThread.start(); + LOG.info("Input listener thread was started"); } catch (IOException e) { LOG.error("Connecting client to server failed"); e.printStackTrace(); - disconnect(); + disconnect(false); return false; } return true; } - public void disconnect() { + public void disconnect(boolean initialized) { + LOG.info("Disconnecting from server"); + //close listener + if (inputListenerThread != null && inputListenerThread.isAlive()) { + inputListenerThread.safeStop(); + } + + //send goodbye and close sockets if (clientSocket != null && !clientSocket.isClosed()){ - try { + if (initialized && clientSocket.isConnected()){ send(Constants.CLIENT_GOODBYE); - inputListenerThread.safeStop(); - in.close(); - out.close(); + } + try { clientSocket.close(); } catch (IOException e) { - e.printStackTrace(); + //e.printStackTrace(); } } } @@ -81,6 +90,7 @@ public void send(byte[] data){ try { out.write(data); out.flush(); + LOG.info("Sent message: " + new String(data)); } catch (IOException e){ LOG.error("Client cannot send data"); e.printStackTrace(); @@ -93,12 +103,15 @@ public void send(String data){ } /* this is called by a listener thread when data were received*/ - public void onMessage(byte[] data){ - if (Arrays.toString(data).equals(Constants.END_OF_STREAM)){ + public void onMessage(int len, byte[] rawData){ + String data = new String(rawData, 0, len, StandardCharsets.UTF_8); + if (data.equals(Constants.END_OF_STREAM)){ //End of stream, connection is not available anymore + LOG.info("Client is terminating after server disconnected"); + disconnect(false); } //toDo do something with the received data - System.out.println("New data received: " + Arrays.toString(data)); + System.out.println("New data received: " + data); } public boolean isConnected(){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index df89f8171..5ee625583 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -8,7 +8,6 @@ import javax.net.ssl.*; import java.io.IOException; -import java.net.ConnectException; import java.net.InetSocketAddress; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -55,8 +54,9 @@ public TLSClient(ClientConfiguration clientConfiguration){ sslParameters.setNeedClientAuth(true); sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher - //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever + //toDo set further SSL Parameters sslSocket.setSSLParameters(sslParameters); + LOG.info("TLS Client was initialized successfully"); } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ LOG.error("Init TLS Client failed"); @@ -75,16 +75,31 @@ public boolean connect() { try { sslSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), clientConfiguration.getServerPort())); + LOG.info("Client is connected to server " + clientConfiguration.getHostname() + + ":" + clientConfiguration.getServerPort()); + + //set clientSocket timeout to allow safeStop() + clientSocket.setSoTimeout(5000); + out = clientSocket.getOutputStream(); in = clientSocket.getInputStream(); + //add inputListener but start it not before handshake is complete + inputListenerThread = new InputListenerThread(in); + inputListenerThread.register(this); + //start tls handshake sslSocket.addHandshakeCompletedListener(this); + LOG.info("Start TLS Handshake"); sslSocket.startHandshake(); + } catch (SSLHandshakeException e){ + System.out.println("TLS Handshake failed" + e.getMessage()); + disconnect(false); + return false; } catch (IOException e) { LOG.error("Connecting TLS client to server failed"); //e.printStackTrace(); - disconnect(); + disconnect(false); return false; } return true; @@ -96,9 +111,8 @@ public SSLSession getSslSession() { @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { - //start receiving listener for IDSCPv2 communication - inputListenerThread = new InputListenerThread(in); - inputListenerThread.register(this); + //start receiving listener for IDSCPv2 communication after TLS Handshake was successful + LOG.info("TLS Handshake was successful. Starting input listener thread"); inputListenerThread.start(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java index 61bc146ab..7efa5e8b3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java @@ -8,6 +8,6 @@ public interface DataAvailableListener { - void onMessage(byte[] bytes); + void onMessage(int len, byte[] bytes); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java index e4bdfe6b6..4046d7e5c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java @@ -24,18 +24,20 @@ public void run(){ byte[] buf = new byte[2048]; while (running){ try { - if (0 > in.read(buf, 0, buf.length - 1)) { - notifyListeners(Constants.END_OF_STREAM.getBytes()); + int len = in.read(buf, 0, buf.length - 1); + if (0 > len) { + notifyListeners(Constants.END_OF_STREAM.length(), Constants.END_OF_STREAM.getBytes()); running = false; //terminate } else { - notifyListeners(buf); + notifyListeners(len, buf); } } catch (SocketTimeoutException e){ //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye //alternative: close socket / InputStream and catch exception //continue; } catch (IOException e) { - e.printStackTrace(); + //e.printStackTrace(); + running = false; } } listeners.clear(); @@ -51,9 +53,9 @@ public void unregister(DataAvailableListener listener) { listeners.remove(listener); } - private void notifyListeners(byte[] bytes) { + private void notifyListeners(int len, byte[] bytes) { for (DataAvailableListener listener : listeners){ - listener.onMessage(bytes); + listener.onMessage(len, bytes); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java index 1fd437238..8c5d40fa3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java @@ -26,15 +26,18 @@ public IDSCPv2Server(ServerConfiguration serverConfiguration){ } protected boolean start(){ + LOG.info("Starting server"); return (isRunning = true); } public void stop(){ + LOG.info("Stopping server"); isRunning = false; terminateRunningThreads(); } public void close(){ + stop(); if (serverSocket != null && !serverSocket.isClosed()){ try { serverSocket.close(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index 3eb4c4d36..4e9458d92 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -53,9 +53,10 @@ public TLSServer(ServerConfiguration serverConfiguration){ sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite sslParameters.setNeedClientAuth(true); //client must authenticate sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 - //toDo set further SSL Parameters e.g SNI Matchers, Cipher Suite, Protocols ... whatever + sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher suite + //toDo set further SSL Parameters sslServerSocket.setSSLParameters(sslParameters); - + LOG.info("Server was initialized successfully"); } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ LOG.error("Init SSL server socket failed"); @@ -90,6 +91,7 @@ public boolean start() { } //start new server thread + LOG.info("New client has connected. Create new server session"); TLSServerThread server = new TLSServerThread(sslSocket); //toDo server.setName() + hashmap servers.add(server); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java index 667a7e2c9..38fc8fc72 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java @@ -6,13 +6,13 @@ import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.SocketException; import java.net.SocketTimeoutException; -import java.util.Arrays; +import java.nio.charset.StandardCharsets; /** * A TLS server thread implementation for the IDSCPv2 protocol. @@ -28,6 +28,7 @@ public class TLSServerThread extends Thread implements ServerThread, HandshakeCo private InputStream in; private OutputStream out; private boolean tlsHandshakeCompleted = false; + private boolean sendServerGoodbye = true; TLSServerThread(SSLSocket sslSocket){ this.sslSocket = sslSocket; @@ -47,33 +48,32 @@ public void run(){ //wait for new data while running byte[] buf = new byte[2048]; - //wait until tls handshake is completed - //toDo avoid busy waiting - while(!tlsHandshakeCompleted){ - try { - sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - while (running){ try { - if (0 > in.read(buf, 0, buf.length - 1)) { - onMessage(Constants.END_OF_STREAM.getBytes()); + int len = in.read(buf, 0, buf.length - 1); + if (0 > len) { + onMessage(Constants.END_OF_STREAM.length(), Constants.END_OF_STREAM.getBytes()); + running = false; } else { - onMessage(buf); + onMessage(len, buf); } } catch (SocketTimeoutException e){ //timeout catches safeStop() call and allows to send server_goodbye //alternative: close sslSocket and catch SocketException //continue + } catch (SSLException e){ + LOG.error("SSL error"); + e.printStackTrace(); + running = false; + return; } catch (IOException e){ e.printStackTrace(); + running = false; } } try { - send(Constants.SERVER_GOODBYE); + if (sendServerGoodbye) + send(Constants.SERVER_GOODBYE); out.close(); in.close(); sslSocket.close(); @@ -90,6 +90,7 @@ public void send(byte[] data) { try { out.write(data); out.flush(); + LOG.info("Send message: " + new String(data)); } catch (IOException e){ LOG.error("Server cannot send data"); e.printStackTrace(); @@ -101,14 +102,17 @@ public void send(String data){ send(data.getBytes()); } - public void onMessage(byte[] data) { - if (Arrays.toString(data).equals(Constants.END_OF_STREAM) || - Arrays.toString(data).equals(Constants.CLIENT_GOODBYE)){ + public void onMessage(int len, byte[] rawData) { + String data = new String(rawData, 0, len, StandardCharsets.UTF_8); + if (data.equals(Constants.END_OF_STREAM) || + data.equals(Constants.CLIENT_GOODBYE)){ //End of stream or client goodbye, connection is no longer available running = false; //terminate server + LOG.info("Server is terminating after client disconnect"); + sendServerGoodbye = false; } else { //toDo do something with the received data - System.out.println("New data received: " + Arrays.toString(data)); + System.out.println("New data received: " + data); } } @@ -121,9 +125,9 @@ public boolean isConnected() { return (sslSocket != null && sslSocket.isConnected()); } - @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { tlsHandshakeCompleted = true; + LOG.info("TLS handshake was successful"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java index dfc92f2b3..79f73fbbf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java @@ -76,8 +76,6 @@ public static KeyManager[] getX509ExtKeyManager( //allow only X509 Authentication if (myKeyManager.length == 1 && myKeyManager[0] instanceof X509ExtendedKeyManager) { //toDo connection specific key selection via KeyAlias - - return myKeyManager; } else { throw new IllegalStateException( diff --git a/idscp2/src/test/resources/jsse/aisecconnector1-keystore.jks b/idscp2/src/test/resources/jsse/aisecconnector1-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8cac581c388491153679329a43ce082c6877ea64 GIT binary patch literal 2527 zcma)7c{tSD8=vo(rOY5ROvSaAvW@Q;W9<$ajeQA~J+ojcjL@Yd3?sU>a4(}|m+jh; zx}{vCv6gb_whA{(wh^w914=XpP8dEax+^LgL1F}pDffk2?b4s3UT zAhcMvQr6872pkG>U>l$~LR13*zyNiqBmlr6Fb?cv-KJ@&kq+ja7sO?NWIV!)lDM=O zThg^J9CI+W@tY}GMCmQHwPuFO4OMd*!6A0xpjm7WT$Jq;=N;vugZ0+`MTS{zD>ob%e25AL~8DpY!z+nh%`@Isikt8I|+syQq@DJ$T5ru^A<5_ z<5GeLvAa6URbw>9DO*ReBEe0gbu34*Fjx9Uw1SWO@vo@`CEw+zD;5@4)kIvL7DWQs z>wn}V55|=hni6%XxVPt3Q~Zu+g)Zh4m2{7jvk<(sXMOi0>Vx?uFT}5N6V;Whdf?h-# zF)%Ym?Y%C`pDCl%9kOP3iu>#0*-p=6vS#Wp2QWgGSEL>sbeek>pR_TDJ6rZL@3fQ$52GK0S*iZc4I!AjxXz z9ZS`(rv^gF&F^({3vtVYGQ?!#m2Zq_?N7?LzMDc;)-dT?x@B@Yr)RU*YcA$wtHB$` zW4`l;35;H~pFH;%w`hJk+2gp`J%NJe(K2t#lbkujMcn*G%N~o#@qzdTR{5Eduuznu zaa-d8WC4Dtn1=yNl6zgWkmFOeN~-PGaEfmj-CB;R{==+(@PLO=IJoj`)NNHl!NP-IW2ci9o%D z;`e$(i{u|?DCsBZCk^Gls^0;iKF3(BkAUESWDk)I5A%zNk4G&@i1J<=|rDKxcg?8b`JJUvrh;A*42y_ zO`nO8bz*v?x6g?FN}i;P_0t5~q&&`JLhA3N`)l#H*NVPBJ~!w3B|f5^$JL=eFQ~+eH!XiYI}F z5D4s=upnlG9Fgb(5hwtK0=q#m#7^}D%Y+p%06@VZpeX?b?nHdD%Va*re01^=4xG0nZ0FdmnT&-%}gEpi@(v+f^roH&% zUI#1VhTG`!^?Y?Cr8xb<_pMZPP8%yoY!3p%JMC#{FRPvEacVfR{WNO~F&m}UlocGF zG7~O%=5Nh9KkU^74LLNkDF1W(wPNYpX2@GDvsZQcKk1ED&(>9VrY^HD+-P$9w!wkL z!?w*{jc`Da0~us_>IB?WBV*&-Q;;-7*>Svea-JyX!WD=ZrRJ%lI#ON&#LD_uKf;42 z(yfd@8V|g;Y&2e6{tWPhE=HP0k`8k#* ziWjRVvz04*>r`keuZ|GlQ+^(=dS9o_EiVq^xKI%Q0u*zA^THQ72g(VbR!$s-gGs&Z zSx05Y69LI-udJ-ZhY?XH)~rE=t!Wk59uOBJ)sxI`;+`*8DeIB0+U=-4?o08S+?IUHMW&C-~{V*IT^|w0_=sy+!25y~J66OaoIXeT`3|at-9U8__5}t{{4hr&Rgt0>i z{}t;pOqgMi%P>&@DzS~bwo!5$G24jUMyYL--bUQNn^FLWI{ zI(_X2>9eX`jj#DAwSwUTF9md(%G;w@lV2Zy^Sm+csb*owj;iw0Bj^`FxKTT?rF^)^ zlz&xAU<_9rs!uhGbzFO*`^zKKYIm$>pi9i7OSx+nKcS}y#7%VY;d*{_{}Zc^dQZoE zWT}Kz61-k76P>5M-}b}uRIpwIW2PMWE-H$sj5G+AiE&fSef4pl+++mHKXHnOm9HOa zm>s=oQy#+pRQ-f`FS5ayvR35W)^RHF0OHIpj_wHm3g0$3lLuzR+9kffzq;>tzK;(h zr&(_oKJ`&#yUR$a4e7dDcq!SG$1tbpONmRd4^J$1DZPNN6y$1Pyv9;8RB%nIvx`Fs KwRVuWxBmm2L>qhn literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/jsse/aisecconnector2-keystore.jks b/idscp2/src/test/resources/jsse/aisecconnector2-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..2e9d53bd189ed9b992228bdbbbf3a850e3f0e0e9 GIT binary patch literal 2525 zcma)7c|6ql8=vo(5#w$c$2OU1BqlSy!??04206w#6tlvZV~J)M(_s09Db!TfCPh|` z|GNCQGw$#cFd%X6K{p0t?=ly!#pW}I+&*%02JkOW6U*19>5U6wj z8v`Iotx&3Z#svrj4gp25-$7+r#7G;004);M6l^m(cZ>g1dp{T&CH?AA9me* zdXW4H;uc{xj^6g6Dg1-3Sz!@JaDG>9l;6rjxoODUczsmp)!WkzQ%RZ5WV66zm9Jat z$i19xUK~dz>?M9QZIoqT8UgQ^bAwyK}b8K9% zXG}769C7%)S?1`id5bvaL`(+ueLn#)hk1EG^(f@=y}Px0_%=U5H^+qZV8075>&Fu8 zs?&b#m^-m!sjmHZ_T6B^wpR18C1;{_mT0i1G*v8Y7}f#@JuU|24AwN8E*MhEQ$3F- zT=?{@sm7Ux;+6BGvDYIi?qU5?G7s6H?s%zMI=5O5n7C)_#3iZCmMwG(gQJ2j`7?CW ziF;B8p1Iar+x9D0IR$0m`c}Ovmke#vYX%_B;cR*dd~w;`IMOD(f5H#7#U6GmxBFB} zds~28CsQmcBj6`%~LkORVazu zxGNnpyfT{mXO=-sG&?gzr@DRmf~f}ZtU0+GnLcDN50gA-Z^Hxk`>L7Y#ii7?sK!9o z9I-f0>FonnzKxMy6EY*@zWSwQRP6~MJ_O~izC>Gig52gTqNI&9SdxWooT|)9&~nQ` zf0j?{9dCmcih0{<>l3i2(^@Xr?Pv5(t)xFDZjF0G3|aO-dvfAC$PJF&5Kh^`e%sc7nRFz01LOHXxC8|9JakGRH_fiFU88UKF3Q9@}&voK}1}UhB6y z0FoPJHzNPg6n#+DB{nO8+w|;iN|>Ql39}kmgl>91aC)!dg!dzY>thVzA-x0ju21%J6|Hjhy$1#6*2#XmZ>Ac+d(Uw!8oj$> zh1fTplUlmnD9{N&lauRAxz<$L&|JV7S+70xi*mUYhjf>+u(l?KQ8n3l^(V1k6#uw7rtISi*)#v z7Q7T-!C147=N$9z)E=7ScJ9*bR#E#QJ<^YN97EczMLYg3 zK0dDgadbT{T>JXbhjr7cv8qdP)lPeRU|Ht}PQL%SXJy;L7wD5Mp_SD{JZE#>laVL} z;fcG}^A@-qQjTtP(<@^0sOsTslRl!O7QQ3&tUft({xy|n*xo>Q-xy&W+@v|7Jgbg~ zq{dcOKJA}*^uyVU^1Fvkl|ZHIhMkOHr>YKns;C!9i9q5IAI#Z?J_fm!BO7n81{X#7S= zg!>WAKr09YmMblX7eJ9rVu1`4fIMWnMm4dcU(7GP*cLMXNv6Od#HZq-yGS%D-H znM49jOvrRiB@>dAn*K#W#{UsP8B|=4pr8o1b*4E`NCa@_pAq#~WJ{J6o5>+CLs(V> zvK5m|2w|~70?1*4(rGfw+{ywJ0o(q4FKNY>5dkXFRsbNNA^?DNf*8_R(QZT@nlB3M3w_AFABOBq z_x*CCCkURnEKGQ z{UUhwK8JbIWD@ro0af(CF4g=eWNGn3yqVjALnA#wcj{z|Kqt|W{TS_bj~1&ihHSw) zqZoS1`*coO4X96@n9;7VzT!HZCmeRJ>=t`blP7T6mzy{@%reEEpM&O;$%_xB%YAHp zbpuiN%!a6p0z7$UvdlH_a`Hm1-6yDeRgMrw+b?i|23bI500?kd1jI>S;Qr0RzX1d+RpjhXxiA|ouC%_MUE z5fzceHV$J&6QygQkF1=uTf^a-008C$I)e6pa}b(p`IiqCFNPbzV@OZ@mnS}tCtxy| zY`#D$Nps@5@#i(S!%(35-|l3f|5yNccs*M+7zbpDukRTLX_cZrZ*^vcAk2fan10I#Ya`@S7wR+{JvZZ zh&447^ZMsrOi#Q;n)oxx@@~=3)O~o&?o!-nWeXRvwS#$;=<<|x+u8fIV#h1^sNL>Y z)mx^og@=9lVW=>lQgh@O|5uMgvo)nj%AHygdoQj}f#ARgpqQ}tWi0JgqnN>YHI?iYR*_B@Mmx!`ttg+W9?Dlb=!Z8xLu^rKg5U1@|%TMeLRVnTb>%(XEHC z+iHMbZR0$e%5pJFBkc3EFBJPYo*9^a9nAi)Qf9lwE^M&b=6vNlyp^ZlE)Bg6Nko4E zU631*>?2Ll40u1>uUW;`YfXr{HGDc*GH@r?VyjPH)LS1rrTpeT7InC*%v5mOozTJ3f|FS{%0sz z--dKVd4Ew$l=LMe6y5()EClCwP#-e%ks@k`#&%nBa7|76WwW?*Jk!O^=g50%Zv^4B z5AhEyK6My5IV(CW>lzJI3yUBThfTUqTc6bXUbZXf0dG%i?v`KYH*2ec+!I=s{a7Po zvcl?+IK*vpjH_1h1YXBUdeFGcgM0UOyLhZu0gXjz#EvfovTo}XtM0xaSrU$9 zV;QP!7;2~_z#40{aCeV)(n#QVk^dREQCYm_6s$nlA|(_{Y1u-}+dWAyY;KtJ^k(n+JA^zEVMw_`v1w3^Efs4=UU z^$Q6D{4ow=^Q@Wg0B)bqFwXE*1EQhey8hTjN6C+$>eqILCuLVMV>bq2ltVsrC0FWH zG2>?fjA>cVN0+QaT5Ood72DJHSg?1M7Ch>X)4b+%w>44rgM@#iR4@P3$M7I}P~@?h zw#OH9v3zP*)h!zDy!gx5EfZiUFl$?dVSvQ$4lsoCcFSXn9$PxjSB>E64P^RZ@2d?LL@g zx6Le09${MEOqQ*sxw^hpp2)_PIKQ}Z`=xH0uz+f`y~8Nx*~w4d!8=G0PnT6XOZz$% z(YqlVcoPBv9+pqUcvygv`}JAT?izYXbZ2#s}XI9FiBp^2DY&d zmP5OLLHN-BldH>%%XySA3R~$(5u6wz4pv`IC}Na6c@Z&;{Sh($EdUE+md~kT&@S8j zzHue4gzhbyF z2ATUIkMEY6y*QFCW40jA;MVLK%TNN_t8_5h-%!1Ex(zySCS6@;>=2bun|w3rl^^r& z@H$QQM0{e>q0Xt;myHg2`QbOM0`i|&h~KCjP12!iKiwI0Eb%i5+eiVNb~^Tyn~FvE zY2Wh`=5z^t@drE~d@OOTf023jyX5erSAF&2zUd-C+gym{&*BR{(buWElPa1USCJ`U z^puI+El}Frcx0W3EAj9D8LR?6ij50vnOnyHfG@LnZ8^?sS7c0uwuVHiJiSMA;7;)sO-O0(A89A!Yo544 zE_sl5FnwnxM-=d;ckc9sV>cg!S*YYN3NreM>JM*p?=@XjF)ZPS5R}JfPIvZp9&Wgy zeZ;dwZ|7u{wny~ueM7-&7pm*7;atnTCh%W$#XHQ_qFz8X75h0jS;4`eO-r@!Ayw-m vzBj!eU8}##_KO;_e`T)owl{P|`L_lqUG?i05<5)mu+0@`1t|N}%b|Y)9u*Bp diff --git a/idscp2/src/test/resources/jsse/client-truststore.jks b/idscp2/src/test/resources/jsse/client-truststore.jks deleted file mode 100644 index eebd40f4c4da3ded8f6a3a60042f0812e1a3b4b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1954 zcmezO_TO6u1_mZLW=c+EU|VGZP~d6DPw* z#)ZZgw$)V{@Un4gwRyCC=VfGMWo0n1HRLwnWMd9xVH0L@aWxb+5Cn0!c(~k(5=-+k z^3zg_3?&W3L4wRY0-i3x3PJh#B?``t3PuKoW(IQNyoP3m21YIbQ53xn&{ zeeaKbu+wmVuBJ0fL};VO;gva4Z@b++dT+b$;;*OX)!HjXDkL9CG?IDVRCS@>JAlD+ zQS1B*8l^wHH>KZpSRLCT%(83y;r`Xey1 zX-?8|%`1w__l344{FYAL%D(8+zth|+g7){`pFj7t*(BBGS0`VqxJ=a`|JCzdDJ5mXkD`xyeE7Hf4C}H7GT-kP?00S! zUn_ZZe$Rz+^Rh>rZ}`QZ?%rveT5-Vc3@Svzn1d@mwsQVDx-U;=gzJO+&p)d{L&}ed8U`Xv|J#?B;5Znv+J*;+hQk1?0mFAL*VBkhGn0oy6-JKaMx1zQjG6;y{mf5_U;oq z=5xThx|sQrj_|6Pk9aRFozpT;dd|GS#?rYRr3)we=>9G}b5TZs??t0U<_qC&O_!~U zGQQlsHBY5))7x$LFK@Z{fb*irqcd5KS-Oigk1de?SKU{eXzkPVXS#ULw+C%|H~h%? zyypHt^*L(h7yH*`oQkgbvfbwmht@6W<9qtT&A|DOwYW41mi>$lBeLHMVD@_g%zkGe z*^iMCIRv?Bk?o93fZ5I%mhG&G$kpNoqQEEy=4w7rt`06ug5_yKneJ6~!Vb}x`@eqN zQCPSADgXLbaml@!`^sneB*$HN^6==AiD{RXP0df`5%u{K*ewvlx;MCTrEOz@gNwiD z@1I{@IoA5{PVTyEQJ|=JqI+{#F(zj3fhglyE1tE#+^tn`Q8c@* z>~(?bwvLR~r--eo0>#U8oAl zbd4Vj8s8#iyU(phUFHic-?zRmC#0C&@bqv0;zr7{U7LY9C=bfB7#Qdo=q%7$pwXt5 zQBqQ1rLUh{l%toJS)7`zmj*AU^-@yxGgFH7fN};QY#iEb!1A4)k&(s2z|Ft~#y4PU zvw)hBl3$*elb;CGfz6~MU@4!Rn4DTv0xIYAKn%1r3@!!cuJ4(^`8iPfliCE?!s!nE zG9S6pZ^Sh!d%j(@oM&Q5#XFYD51=`u78&@%dR=X2lBHEjR%|Gxfq zld(MM^Cp|32YnOo-8-zi=Z;LA*FuT!RzA)9k7if!PFvdZa>LW7C9kF&SjJTDRx`Kw zNpFL<;!AFc$4_@Smj#L~+|;okV_k9cjra{8R<2ao)2g&_y-=oAo#OZUHvjx9J<}(o z*nKLJxi*O}Zq>$kmbhR?g9$ltr;bl|-Ku4G>1SK|SG@!c=Q(i+MVGe9&Sh79EZwkm z_PsrBqM|EXvr6uS@Y%gx!XY?sYiv*Z!4~nHT;H^*$E!}u96Zz4qxm$qaG`0!$_rC& SIRsq4$r!~{@WDl3D?0!nu;#!3 diff --git a/idscp2/src/test/resources/jsse/client-truststore_new.jks b/idscp2/src/test/resources/jsse/client-truststore_new.jks new file mode 100644 index 0000000000000000000000000000000000000000..998f04c7d601ba0540b4d4d15fe86bdcb7af0bbf GIT binary patch literal 1974 zcmezO_TO6u1_mZLW=c+EU|`Jf5m7g0V2#i-HLzr0V9qvZVoo<`V)9?W%*4pV#L2LU z@x9*Bv>WXPylk9WZ60mkc^Mg5Ss4tR47m+B*_cCF*o2u}Tn&W{1VJ1w9xk_{#L~Qs z{It{}LpcK(kRUUUsHaP?LQsBwi9$$fafyPnqk@rvp@o5*IIp3Fp@FfXp_!qPfl-t= zuQ8BoWCrC@#f~OMC1j^FvNA9?G4eAQG%<29H8CvpkK@{zD!3fL8WmPNPq_~x&Fw@qo$5yw>f^z%Zipp*lu$0)ca^by}UFXjJ-QyZ?{>+ZV)9WPPWv_2jS{fCjs&lH-W0AJn z^d`@i3n>%5^?q;5x~aP$C}VQp@AKi}X;aJWgPVg@UHk&fq9!lNkFaBXHhY0NA8+i_ z0|h1%t(fN-%nR$yK6gH$%}Ddu&jpRiqF$e_G?cswTARIFYr)q`)f4V%ADcNjK_c{Q z_q-7GTP|1ZCae^(R(4Tf{QLLpf@vwwp0dPEJAHcYPH;|SEiO$0XT+SFY+JMu8SxV^ zBfbM>#A}d@$jFEsg4{I8fF{5U2+Vv2MwZ|VXcA@MKtv{&F^~erGcc12gEBcde+QQ) z!Lm4^?6+E_C(QqrT35-%gSVdjJEkXlX2wb9;|r=H&qqG5@jDQwm3?>1vkmJM4k%n( zWv&{pG$U!(o-1X4P89uFp5kG)-PAZD(@k=FV1bFvhNg&8W6iMqlh41(Dg6<-eZFGO zN~O6gqQ3`)HTed1&Qp6Y(r*y`BceUJ`C-GRNBlWeWeayq(t8#haQL8tV;V2-&qF^h zo0Pr35$7su*`aXqw@F9hk+cPe1tJctZOfML_ddntp6}9fIC9deG*Ly7N>#??wqo-l z84qW^R&lRtdE3}~FXyK<>)157N;ibrNN7Cy_8h_%#>n1pqxPn8;3R< zu*_#?WMuI$a5Hd$@eP>TETCqjMyJrDyeHG|6o z!KqSj-)zyd{agKa!QYw;4yWw+wJm3*g11jl;{112E#n$j-WJx6t=(6%)q*aUGGw#; zy5KBQD;fNflWV%jv40{$Cu%Mn59m$5oqTVV=eg`$_O5mFERRlnzrL02cVNM#Bj2{L zt8KjXc+FOed5P!u`?=4S4b1Y%-??DNvK1R{JxO@1*&4G}H&rvC`l;9g`I=)%Z~u9) zG}_O%emwg|cZGCR_eZxl%g_5C^<^ZTee+9vMniO0Y-gh0r`;LVbKcZFJ($0dnWyoe zYrYYqA=e$%<_Ut+7Vmn}bu&WYORM6`YKBXK_xC*O*&X-8P$I!$Zrc3ySu?wxy5@h* jKJsPXQbv^>U)0#*vbc9$N>rMBDW~+|HRjd{yhWM-qpIG& literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/jsse/server-keystore.jks b/idscp2/src/test/resources/jsse/server-keystore.jks deleted file mode 100644 index 5e8f8003fce1cb4f166cd15a7a359cfbcbc20c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4494 zcmaJ^c|25Y|DMeK(ap7;GczuzC{^SQ5c-}iOC_xF6y_qxu>`pG&71cLnY0)xnIVX#;n2n2S1 z?D=yS1R?_ic-S#OM@}V54u*j*KG7t<8Tej|g@!d%$&@9Di+iZOxG9G!BW zQMqk)RKwU^o_f6&^(orgd{=IiFL6cpf>9%NBCgMPcRYZiov7LTz1C8W%F}VM=A1Mv zE;y~p;q_v)`%|n$%eJ$v*@D8Y$&x*vn~jJY`@U|f%ZfLndPei9w`JHxhl28~On&t4 z58{7n!yZW(ouSg=nak#qU6)~4yZyDUbtvkJn!n5Lroc`PZ`Hv^)0^mUELE;@h!i0{ z$F{biv65eJR^I<*wt2|om95KfQ~O8IYu_y$=jreB5O0XeFvMvTn(prf+&A{E(q-U3 zKo5x=vGE*gsIxDHcAg#yxnxC^HqM9SgXS9Vf91No^@UgqoUvi&B%?nZQS2%D1H=0r zox-g6mW2g!`#35t^^)?Ze+S@2Q@dR@S^KXGTk>TTbxP$-E~pb$|8#Fi4(t; zq7iNC`--YsbjzZ(X3px6JCj^AW|6Y>Yi-L1$A`2oI_7FQ(OcZq%`zCZrTw=a?@zWM z6lGC2_4GZ2S(3D$;x2J=uZGp0>sbtZFUjXf_APHpDn#iG8`WGlnIhSb}`0RAY_mtZszSk_Y)+O9)cZv-Ev!#6%xH(#ZO;s+8pkS7jh(IW145aZP?} z3sz}RuvK@#-9TA7SJA(N%$L4HNAG%jx4!Q5v{>P@*>&5GSG3}18(*?l%axpNSoWKa z4BJ=O-#jlleh~F&K0czIn*D65fjWz0kdK-?P;v2khF4lw^}+G*Big$ z$57*fPG*fMdnczSYNiyKWT}7eTh&1EX~6W1b0A?o>{!WZ)%rI7KKRhf3440_7V^kV zT?=%;ciG5s^<9;~^Yr^V9y*J>EJsD-`?P|~S$&<%p2C^c7JNfl!3M`Oo}U+Y`8GFW zd-vq>!kO&ig*jRIuQ!i9Npf6>zeLp36?sB<{Ob9w!IpVA^^A!uf%}|3zkZ(tsW+1P zqPe&{OP0HCC0EJ;xQFYy1^g$MKgm7dgmp?EL?M2dh4f(L^^ zaZ+|$)klUm^eQYXO-?JP3WIlWqXaeGQB4Xq-Q+3vdCxAt`=a-15R?Vw-rhs%#8!R) zmz=h|@gw(Ivy-Qinhimj@M@93dMw|UWr3kGN1TCxJiP@S+=yx6C_l+R_qTn*PHucVcxUvPiZ$v&dz z^YXkADgbJ78z=dNaG`v$G@X5~AeRv>-qs-7G2G)FFFeb9i(aKa&V#}uc}~gREIM`Z zdR@uFbVz5s-z&j%H0wrPwaYcyR{QkY@QYiY$sqxPG~s(8+0HRT;E5&!Rt8G?hF!Pi260GGBB33(dt zeoknfAKTOdD!aKxi+9>47J4ONDDUfpN%w&cgyl=F-4Fhb2+Ne&`3?W(12ucfxz(TW zvTrqg>1Ac67GzEG)u26^#9~@<8#^iJ+>zc}>lTxfB*e?;iI_LeZj;wai_qTIB{w9P zA+@$GnVi4N7K|hnui2q0w1y<*P?D6N{*9Eco>Pw!o9DBj$*%v@n|PUSCDn2s!5`Xs z;zQ%vM}bz6ndN^=6%yO1A?j|B3uuC|});#=@%ZlUeAW~#EkZ7rc& zhj;o$;>j`X*yp_;mHtA- zZaaY+V;%Mm7_xo~>i}n&+qNN|NS~@hvXlsP=ExuYW2y3C ze%Ef%8x2*RX&*l>FbZyr^)t=M*%(Wt|7`O4xNjt`0oMXk(3=8{-8-B$4(X#-FMCB^ z0eUu~6GYRIvk}`q!;cRxcA3k`UXesg6isCgbwJ-gy98cNHE%QKI!m}0W%w>Jv&!Qe z2T$;7{5|6BhCM0%{u)O7hFKw%S4x)7;hT^EvY)Xo0gltjDPoB3^|A145^bx0Ja1Ou z!yRdzV_N$va|iy^i7n>RgbI6s^uz5lIM{Yh^RSq|VronVWv~a=BmGeSmCG){Qy{5w z^kEXUYj@lv`7pWMZ2dfYr>|nc6~TVL2Q!c?-B3}#QL0CrI7)#}tpV%~M#m+__6Oaw zz2kG*Te%X>i8d~B$z9?-xktyqIyE|rsJMmq@#fncV>W=g_ zjf=}z#g*yX$g6CJ6?n$K_c;0_pqV~FQy-+`Xtdv2mMjUip?aRN7E&KXD1Iz{xR{)W z3U<)=bc5$1CZ+R?ueYRlf(6)(z*qWi*v=-o!Bo9(-=>%Wr5)$RZZj|;Fj(T~H_tHH z6A}bqFlp#A=MF~g`#y_}(SuwRFQwycSky!x0r1>|XK=;U&Z#47v(7SWi_xncj!fqM z)D`$NR$TL@+a8vwg@O=pf?G7KuLt46aN{xC2sv+l7V~N4{!SY@v53qoP4MU?BcJ(l zTB@zDQRf>jsRm}Tm9+7`-c1!8-+N)F%mf?4Y`^f4&&>Iqz4ec zZcxxr>fXk9I=Emw|2_aZfacdaY8ok9yGR|)gE~K$+TMD!SOfFdF_U#C z@)TWvekgb~+VVN~`Uh9pqx$#LiY&!~^l(i?)A}cO7laI!vNn-@@%&6- zb47x?u^$Dp`%up>?04mGFv1`J2%!G876F4nA!J#A>@UCt0|0SAEbBs+aFn167VE7b zA>rWbE^g=Qhj9>h`geVaJ7OeU9sR^fbAT~9CFwVujEn*dhFt};0F8fP01_qlPYy?~ z08e)>JJOE7WAgR#!aCSFV0^K^N>u#U;Ll?Uz?cE1f6+l9{~mz>)nC!l!xR8H{D0gm z9*&fh6(=1)9Es;9h3DYq>4|Z`dinm{Q~%DM`3s;kUN?*q7Qs0wwmkLHL* zma5c6o-efVE~Yg&OiQrtu`UdGB-6QDe<;0@HqaD!;!0C2q|N-y<8Ey}N^3;^jhH3h zF4}i*FR;gz@o_shl+REXbn;Q4OXTn@dYs)U3# z4jbXtYJ>!5ku8WFx9SKl>oQ6z-&L%{QZo;v$7v8?nKXv#E3X<=N10LP+32D|Ul~q3 xTi2Z}@4K}q8t80BrK0L4(d_Gz*0VRpzEVGZP~d6DPw* z#)ZZgw$)V{@Un4gwRyCC=VfGMWo0n1HRLwnWMd9xVH0L@aWxb+5Cn0!c(~k(5=-+k z^3zg_3?&W3L4wRY0-i3x3PJh#B?``t3PuKoW(IQNyoP3m21YIbQ53xn&{ zeeaKbu+wmVuBJ0fL};VO;gva4Z@b++dT+b$;;*OX)!HjXDkL9CG?IDVRCS@>JAlD+ zQS1B*8l^wHH>KZpSRLCT%(83y;r`Xey1 zX-?8|%`1w__l344{FYAL%D(8+zth|+g7){`pFj7t*(BBGS0`VqxJ=a`|JCzdDJ5mXkD`xyeE7Hf4C}H7GT-kP?00S! zUn_ZZe$Rz+^Rh>rZ}`QZ?%rveT5-Vc3@Svzn1d@mwsQVDx-U;=gzJO+&p)d{L&}ed8U`Xv|J#?B;5Znv+J*;+hQk1?0mFAL*VBkhGn0oy6-JKaMx1zQjG6;y{mf5_U;oq z=5xThx|sQrj_|6Pk9aRFozpT;dd|GS#?rYRr3)we=>9G}b5TZs??t0U<_qC&O_!~U zGQQlsHBY5))7x$LFK@Z{fb*irqcd5KS-Oigk1de?SKU{eXzkPVXS#ULw+C%|H~h%? zyypHt^*L(h7yH*`oQkgbvfbwmht@6W<9qtT&A|DOwYW41mi^vFA+p~KVD@_g%zkGe z*^iMCIRv?Bk?o93fZ5I%mhG&G$kpNoqQEEy=4w7rt`06ug5_yKneJ6~!Vb}x`@eqN zQCPSADgXLbaml@!`^sneB*$HN^6==AiD{RXP0df`5%u{K*ewvlx;MCTrEOz@gNwiD z@1I{@IoA5{PVTyEQJ|=JqI+{#F(zj3fhglyE1tE#+^tn`Q8c@* z>~(?bwvLR~r--eo0>#U8oAl zbd4Vj8s8#iyU(phUFHic-?zRmC#0C&@bqv0;zr7{U7LY9C=bfB7#Qdo=q%7$pwXt5 zQBqQ1rLUh{l%toJS)7`zmj*AU^-@yxGgFH7fN};QY#iEb!1A4)k&(s2z|Ft~#y4PU zvw)hBl3$*elb;CGfz6~MU@4!Rn4DTv0xIYAKn%1r3@!!cuJ4(^`8iPfliCE?!s!nE zG9S6pZ^Sh!d%j(@oM&Q5#XFYD51=`u78&@%dR=X2lBHEjR%|Gxfq zld(MM^Cp|32YnOo-8-zi=Z;LA*FuT!RzA)9k7if!PFvdZa>LW7C9kF&SjJTDRx`Kw zNpFL<;!AFc$4_@Smj#L~+|;okV_k9cjra{8R<2ao)2g&_y-=oAo#OZUHvjx9J<}(o z*nKLJxi*O}Zq>$kmbhR?g9$ltr;bl|-Ku4G>1SK|SG@!c=Q(i+MVGe9&Sh79EZwkm z_PsrBqM|EXvr6uS@Y%gx!XY?sYiv*Z!4~nHT;H^*$E!}u96Zz4qxm$qFj`}+)3Qdx Ss}t|%#;}DMPmB>*G!+0m Date: Tue, 3 Dec 2019 17:06:56 +0100 Subject: [PATCH 028/237] Implement a custom X509KeyManager for enabling certificate selection via a certAlias --- .../aisec/ids/idscp2/Client/TLSClient.java | 4 +- .../idscp2/CustomX509ExtendedKeyManager.java | 121 ++++++++++++++++++ .../ids/idscp2/IDSCPv2Configuration.java | 10 ++ .../aisec/ids/idscp2/Server/TLSServer.java | 4 +- .../aisec/ids/idscp2/TLSPreConfiguration.java | 16 ++- 5 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index 5ee625583..bd12ee2a9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -37,7 +37,9 @@ public TLSClient(ClientConfiguration clientConfiguration){ * connection specific key selection via key alias*/ KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( clientConfiguration.getKeyStorePath(), - clientConfiguration.getKeyStorePassword() + clientConfiguration.getKeyStorePassword(), + clientConfiguration.getCertAlias(), + clientConfiguration.getKeyStoreKeyType() ); SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java new file mode 100644 index 000000000..86ea63919 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java @@ -0,0 +1,121 @@ +package de.fhg.aisec.ids.idscp2; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedKeyManager; +import java.lang.reflect.Array; +import java.net.Socket; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.Arrays; + +/** + * A custom X590ExtendedKeyManager, that allows to choose a TrustStore entry by a given certificate alias and + * delegates all other function calls to given default X509ExtendedKeyManager + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ + private static final Logger LOG = LoggerFactory.getLogger(CustomX509ExtendedKeyManager.class); + + private final String certAlias; + private final String keyType; + private final X509ExtendedKeyManager delegate; + + public CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate){ + super(); + this.certAlias = alias; + this.keyType = keyType; + this.delegate = delegate; + } + + @Override + public String[] getClientAliases(String s, Principal[] principals) { + return delegate.getClientAliases(s, principals); + } + + @Override + /* returns an existing certAlias that matches one of the given KeyTypes, or null; + called only by client in TLS handshake */ + public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) { + if (Arrays.asList(keyTypes).contains(this.keyType)){ + if (Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { + LOG.info("CertificateAlias is {}", this.certAlias); + return this.certAlias; + } else { + LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); + return null; + } + } else { + LOG.warn("Invalid keyType '{}' in chooseClientAlias() in class X509ExtendedKeyManager", + Arrays.toString(keyTypes)); + LOG.warn("Expected: '{}'", this.keyType); + return null; + } + } + + @Override + public String[] getServerAliases(String s, Principal[] principals) { + return delegate.getServerAliases(s, principals); + } + + @Override + /* returns an existing certAlias that matches the given KeyType, or null; + called only by server in TLS handshake*/ + public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { + if (keyType.equals(this.keyType)){ + if (Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { + LOG.info("CertificateAlias is {}", this.certAlias); + return this.certAlias; + } else { + LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); + return null; + } + } else { + LOG.warn("Invalid keyType '{}' in chooseServerAlias() in class X509ExtendedKeyManager", keyType); + LOG.warn("Expected: '{}'", this.keyType); + return null; + } + } + + @Override + /* returns the certificate chain of a given certificateAlias; + called by client and server in TLS Handshake after alias was chosen */ + public X509Certificate[] getCertificateChain(String certAlias) { + if (certAlias.equals(this.certAlias)){ + X509Certificate[] ret = delegate.getCertificateChain(certAlias); + LOG.info("Certificate Chain: {}", Arrays.toString(ret)); + return ret; + } else { + LOG.warn("Invalid certAlias '{}' in getCertificateChain() in class X509ExtendedKeyManager", certAlias); + LOG.warn("Expected: '{}'", this.certAlias); + return null; + } + } + + @Override + /* returns a privateKey of a given certificateAlias; + * called by client and server in TLS Handshake after alias was chosen */ + public PrivateKey getPrivateKey(String certAlias) { + if (certAlias.equals(this.certAlias)){ + return delegate.getPrivateKey(certAlias); + } else { + LOG.warn("Invalid certAlias '{}' in getPrivateKey() in class X509ExtendedKeyManager", certAlias); + LOG.warn("Expected: '{}'", this.certAlias); + return null; + } + } + + @Override + public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine sslEngine){ + return delegate.chooseEngineClientAlias(keyType, issuers, sslEngine); + } + + @Override + public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine sslEngine){ + return delegate.chooseEngineServerAlias(keyType, issuers, sslEngine); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java index d4780f2e2..c87254a6e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java @@ -8,6 +8,8 @@ public abstract class IDSCPv2Configuration { private String trustStorePassword = "password"; private String keyStorePath = null; private String keyStorePassword = "password"; + private String certAlias = "1.0.1"; + private String keyStoreKeyType = "RSA"; private AttestationConfig supportedAttestation = null; @@ -42,4 +44,12 @@ public String getTrustStorePath() { public String getTrustStorePassword() { return trustStorePassword; } + + public String getKeyStoreKeyType() { + return keyStoreKeyType; + } + + public String getCertAlias() { + return certAlias; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index 4e9458d92..2fcdc06df 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -35,7 +35,9 @@ public TLSServer(ServerConfiguration serverConfiguration){ * connection specific key selection via key alias*/ KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( serverConfiguration.getKeyStorePath(), - serverConfiguration.getKeyStorePassword() + serverConfiguration.getKeyStorePassword(), + serverConfiguration.getCertAlias(), + serverConfiguration.getKeyStoreKeyType() ); // create tls context based on keyManager and trustManager diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java index 79f73fbbf..525bd2f90 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java @@ -26,10 +26,10 @@ public static TrustManager[] getX509ExtTrustManager( InputStream jksTrustStoreIn = Files.newInputStream(Paths.get(trustStorePath)) ) { /* create TrustManager */ - TrustManager[] myTrustManager; + final TrustManager[] myTrustManager; KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(jksTrustStoreIn, trustStorePassword.toCharArray()); - TrustManagerFactory trustManagerFactory = + final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE /* filterTrustAnchors for validation @@ -58,16 +58,18 @@ public static TrustManager[] getX509ExtTrustManager( public static KeyManager[] getX509ExtKeyManager( String keyStorePath, - String keyStorePassword + String keyStorePassword, + String certAlias, + String keyType ) { try ( InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)); ) { /* create KeyManager for remote authentication */ - KeyManager[] myKeyManager; + final KeyManager[] myKeyManager; KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(jksKeyStoreIn, keyStorePassword.toCharArray()); - KeyManagerFactory keyManagerFactory = + final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE keyManagerFactory.init(keystore, keyStorePassword.toCharArray()); myKeyManager = keyManagerFactory.getKeyManagers(); @@ -75,7 +77,9 @@ public static KeyManager[] getX509ExtKeyManager( /* set up keyManager config */ //allow only X509 Authentication if (myKeyManager.length == 1 && myKeyManager[0] instanceof X509ExtendedKeyManager) { - //toDo connection specific key selection via KeyAlias + //select certificate alias + myKeyManager[0] = + new CustomX509ExtendedKeyManager(certAlias, keyType, (X509ExtendedKeyManager) myKeyManager[0]); return myKeyManager; } else { throw new IllegalStateException( From 4bf3b18cd892111afce18bbdd05094b4f17f4dd1 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 5 Dec 2019 15:57:56 +0100 Subject: [PATCH 029/237] Finished TLS communication, add ServerNodeSynchronizer --- .../aisec/ids/idscp2/Client/TLSClient.java | 2 +- .../ids/idscp2/IDSCPv2Configuration.java | 27 ++++++++++++++++--- .../ids/idscp2/Server/IDSCPv2Server.java | 19 +++++++------ .../idscp2/Server/ServerNodeSynchronizer.java | 7 +++++ .../aisec/ids/idscp2/Server/ServerThread.java | 1 + .../aisec/ids/idscp2/Server/TLSServer.java | 11 +++++--- .../ids/idscp2/Server/TLSServerThread.java | 15 ++++++++++- idscp2/src/test/java/RunTLSClient.java | 23 ++++++++++++++++ idscp2/src/test/java/RunTLSServer.java | 17 ++++++++++++ 9 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java create mode 100644 idscp2/src/test/java/RunTLSClient.java create mode 100644 idscp2/src/test/java/RunTLSServer.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java index bd12ee2a9..081b1c09c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java @@ -56,7 +56,7 @@ public TLSClient(ClientConfiguration clientConfiguration){ sslParameters.setNeedClientAuth(true); sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher - //toDo set further SSL Parameters + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification sslSocket.setSSLParameters(sslParameters); LOG.info("TLS Client was initialized successfully"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java index c87254a6e..e4f9f7660 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java @@ -10,13 +10,10 @@ public abstract class IDSCPv2Configuration { private String keyStorePassword = "password"; private String certAlias = "1.0.1"; private String keyStoreKeyType = "RSA"; - - private AttestationConfig supportedAttestation = null; private AttestationConfig expectedAttestation = null; - public AttestationConfig getExpectedAttestation() { return expectedAttestation; } @@ -52,4 +49,28 @@ public String getKeyStoreKeyType() { public String getCertAlias() { return certAlias; } + + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } + + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } + + public void setCertAlias(String certAlias) { + this.certAlias = certAlias; + } + + public void setKeyStoreKeyType(String keyStoreKeyType) { + this.keyStoreKeyType = keyStoreKeyType; + } + + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java index 8c5d40fa3..237711cee 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java @@ -5,19 +5,19 @@ import java.io.IOException; import java.net.ServerSocket; -import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; /** * An abstract server implementation for the IDSCPv2 protocol. * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public abstract class IDSCPv2Server { +public abstract class IDSCPv2Server implements ServerNodeSynchronizer { private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); - protected ArrayList servers = new ArrayList<>(); - - protected ServerConfiguration serverConfiguration = null; + protected ConcurrentHashMap servers = new ConcurrentHashMap<>(); + protected ServerConfiguration serverConfiguration; protected volatile boolean isRunning = false; protected ServerSocket serverSocket = null; @@ -50,13 +50,16 @@ public void close(){ } private void terminateRunningThreads(){ - for (ServerThread thread : servers){ - thread.safeStop(); - } + servers.forEach((id, serverThread) -> serverThread.safeStop()); servers.clear(); } public boolean isRunning(){ return isRunning; } + + public void unregisterServerOnClose(String connectionId){ + servers.remove(connectionId); + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java new file mode 100644 index 000000000..8b5bc652f --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java @@ -0,0 +1,7 @@ +package de.fhg.aisec.ids.idscp2.Server; + +public interface ServerNodeSynchronizer { + + void unregisterServerOnClose(String connectionId); + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java index 342a60b13..1a4d663bb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java @@ -10,4 +10,5 @@ public interface ServerThread { void send(byte[] bytes); void safeStop(); boolean isConnected(); + void registerListener(ServerNodeSynchronizer serverNodeSynchronizer); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java index 2fcdc06df..ce5613615 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.net.SocketTimeoutException; import java.security.*; +import java.util.UUID; /** * A TLS server implementation for the IDSCPv2 protocol. @@ -56,7 +57,8 @@ public TLSServer(ServerConfiguration serverConfiguration){ sslParameters.setNeedClientAuth(true); //client must authenticate sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher suite - //toDo set further SSL Parameters + //toDo uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment + //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification sslServerSocket.setSSLParameters(sslParameters); LOG.info("Server was initialized successfully"); @@ -94,9 +96,10 @@ public boolean start() { //start new server thread LOG.info("New client has connected. Create new server session"); - TLSServerThread server = new TLSServerThread(sslSocket); - //toDo server.setName() + hashmap - servers.add(server); + String connectionId = UUID.randomUUID().toString(); + TLSServerThread server = new TLSServerThread(sslSocket, connectionId); + server.registerListener(this); + servers.put(connectionId, server); sslSocket.addHandshakeCompletedListener(server); server.start(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java index 38fc8fc72..5dac2ac76 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java @@ -29,9 +29,13 @@ public class TLSServerThread extends Thread implements ServerThread, HandshakeCo private OutputStream out; private boolean tlsHandshakeCompleted = false; private boolean sendServerGoodbye = true; + private ServerNodeSynchronizer serverNodeSynchronizer = null; + private String connectionId; //unique server - client connection id, that identifies this serverThread - TLSServerThread(SSLSocket sslSocket){ + TLSServerThread(SSLSocket sslSocket, String connectionId){ this.sslSocket = sslSocket; + this.connectionId = connectionId; + try { //set timout for blocking read sslSocket.setSoTimeout(5000); @@ -80,6 +84,10 @@ public void run(){ } catch (IOException e) { e.printStackTrace(); } + + //unregister from main server + if (this.serverNodeSynchronizer != null) + this.serverNodeSynchronizer.unregisterServerOnClose(this.connectionId); } @Override @@ -125,6 +133,11 @@ public boolean isConnected() { return (sslSocket != null && sslSocket.isConnected()); } + @Override + public void registerListener(ServerNodeSynchronizer serverNodeSynchronizer) { + this.serverNodeSynchronizer = serverNodeSynchronizer; + } + @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { tlsHandshakeCompleted = true; diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java new file mode 100644 index 000000000..c2902a68d --- /dev/null +++ b/idscp2/src/test/java/RunTLSClient.java @@ -0,0 +1,23 @@ +import de.fhg.aisec.ids.idscp2.Client.ClientConfiguration; +import de.fhg.aisec.ids.idscp2.Client.TLSClient; + +public class RunTLSClient { + + public static void main(String[] args){ + + //start client + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setKeyStorePath(RunTLSClient.class.getClassLoader(). + getResource("jsse/aisecconnector2-keystore.jks").getPath()); + clientConfiguration.setTrustStorePath(RunTLSClient.class.getClassLoader(). + getResource("jsse/client-truststore_new.jks").getPath()); + TLSClient tlsClient = new TLSClient(clientConfiguration); + if (!tlsClient.connect()) + return; + + tlsClient.send("hi, how are u"); + + tlsClient.disconnect(true); + } + +} diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/test/java/RunTLSServer.java new file mode 100644 index 000000000..1f2001b62 --- /dev/null +++ b/idscp2/src/test/java/RunTLSServer.java @@ -0,0 +1,17 @@ +import de.fhg.aisec.ids.idscp2.Server.ServerConfiguration; +import de.fhg.aisec.ids.idscp2.Server.TLSServer; + +public class RunTLSServer { + + public static void main(String[] argv){ + + ServerConfiguration serverConfiguration = new ServerConfiguration(); + serverConfiguration.setKeyStorePath(RunTLSServer.class.getClassLoader(). + getResource("jsse/aisecconnector2-keystore.jks").getPath()); + serverConfiguration.setTrustStorePath(RunTLSServer.class.getClassLoader(). + getResource("jsse/client-truststore_new.jks").getPath()); + TLSServer tlsServer = new TLSServer(serverConfiguration); + tlsServer.start(); + tlsServer.close(); + } +} From 7858455cdae82560861ec69e7897fd2ca3ad179a Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 19 Dec 2019 16:13:48 +0100 Subject: [PATCH 030/237] IDSCPv2 new architecture design --- ids-api/src/main/proto/idscpv2.proto | 73 ++++++ idscp2/build.gradle | 2 +- .../idscp2/Client/ClientConfiguration.java | 17 -- .../ids/idscp2/Client/IDSCPv2Client.java | 121 ---------- .../aisec/ids/idscp2/Client/TLSClient.java | 120 ---------- .../de/fhg/aisec/ids/idscp2/Constants.java | 79 ------- .../ids/idscp2/DataAvailableListener.java | 13 -- .../aisec/ids/idscp2/IDSCPv2Initiator.java | 20 ++ .../fhg/aisec/ids/idscp2/InputListener.java | 15 -- .../ids/idscp2/Server/IDSCPv2Server.java | 65 ------ .../idscp2/Server/ServerConfiguration.java | 13 -- .../idscp2/Server/ServerNodeSynchronizer.java | 7 - .../aisec/ids/idscp2/Server/ServerThread.java | 14 -- .../aisec/ids/idscp2/Server/TLSServer.java | 109 --------- .../daps/DefaultDapsDriver.java | 21 ++ .../rat/TPM2ProverImpl.java | 11 + .../rat/TPM2VerifierImpl.java | 11 + .../secure_channel/NativeTLSDriver.java | 25 ++ .../secure_channel/TlsConstants.java | 117 ++++++++++ .../client/DataAvailableListener.java | 10 + .../secure_channel/client/InputListener.java | 12 + .../client}/InputListenerThread.java | 22 +- .../secure_channel/client/TLSClient.java | 216 ++++++++++++++++++ .../CustomX509ExtendedKeyManager.java | 44 +++- .../CustomX509ExtendedTrustManager.java | 79 +++++++ .../keystores}/TLSPreConfiguration.java | 6 +- .../secure_channel/server/TLSServer.java | 147 ++++++++++++ .../server}/TLSServerThread.java | 102 +++++---- .../idscp2/drivers/interfaces/DapsDriver.java | 12 + .../drivers/interfaces/RatProverDriver.java | 10 + .../drivers/interfaces/RatVerifierDriver.java | 9 + .../interfaces/SecureChannelDriver.java | 9 + .../drivers/interfaces/SecureServer.java | 15 ++ .../idscp2/{ => error}/IDSCPv2Exception.java | 7 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 60 +++++ .../ids/idscp2/idscp_core/IdscpConstants.java | 10 + .../idscp2/idscp_core/IdscpMsgListener.java | 7 + .../configuration}/AttestationConfig.java | 3 +- .../configuration/IDSCPv2Callback.java | 9 + .../configuration/IDSCPv2Configuration.java | 85 +++++++ .../configuration/IDSCPv2Settings.java} | 21 +- .../secure_channel/SecureChannel.java | 63 +++++ .../secure_channel/SecureChannelEndpoint.java | 10 + .../secure_channel/SecureChannelListener.java | 5 + .../src/test/java/IDSCPv2ClientInitiator.java | 38 +++ .../src/test/java/IDSCPv2ServerInitiator.java | 47 ++++ idscp2/src/test/java/RunTLSClient.java | 23 +- idscp2/src/test/java/RunTLSServer.java | 21 +- .../aisecconnector1-keystore.jks | Bin .../aisecconnector2-keystore.jks | Bin .../{jsse => ssl}/client-truststore_new.jks | Bin .../resources/ssl/consumer-core-keystore.jks | Bin 0 -> 2441 bytes .../ssl/consumer-core-truststore.jks | Bin 0 -> 1974 bytes .../src/test/resources/ssl/consumer-core.cert | 96 ++++++++ .../src/test/resources/ssl/consumer-core.p12 | Bin 0 -> 2693 bytes .../resources/ssl/provider-core-keystore.jks | Bin 0 -> 2443 bytes .../ssl/provider-core-truststore.jks | Bin 0 -> 1974 bytes .../src/test/resources/ssl/provider-core.cert | 96 ++++++++ .../src/test/resources/ssl/provider-core.p12 | Bin 0 -> 2693 bytes 59 files changed, 1479 insertions(+), 668 deletions(-) create mode 100644 ids-api/src/main/proto/idscpv2.proto delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{ => drivers/default_driver_impl/secure_channel/client}/InputListenerThread.java (72%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{ => drivers/default_driver_impl/secure_channel/keystores}/CustomX509ExtendedKeyManager.java (66%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{ => drivers/default_driver_impl/secure_channel/keystores}/TLSPreConfiguration.java (95%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{Server => drivers/default_driver_impl/secure_channel/server}/TLSServerThread.java (51%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{ => error}/IDSCPv2Exception.java (64%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{ => idscp_core/configuration}/AttestationConfig.java (81%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{IDSCPv2Configuration.java => idscp_core/configuration/IDSCPv2Settings.java} (79%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java create mode 100644 idscp2/src/test/java/IDSCPv2ClientInitiator.java create mode 100644 idscp2/src/test/java/IDSCPv2ServerInitiator.java rename idscp2/src/test/resources/{jsse => ssl}/aisecconnector1-keystore.jks (100%) rename idscp2/src/test/resources/{jsse => ssl}/aisecconnector2-keystore.jks (100%) rename idscp2/src/test/resources/{jsse => ssl}/client-truststore_new.jks (100%) create mode 100644 idscp2/src/test/resources/ssl/consumer-core-keystore.jks create mode 100644 idscp2/src/test/resources/ssl/consumer-core-truststore.jks create mode 100644 idscp2/src/test/resources/ssl/consumer-core.cert create mode 100644 idscp2/src/test/resources/ssl/consumer-core.p12 create mode 100644 idscp2/src/test/resources/ssl/provider-core-keystore.jks create mode 100644 idscp2/src/test/resources/ssl/provider-core-truststore.jks create mode 100644 idscp2/src/test/resources/ssl/provider-core.cert create mode 100644 idscp2/src/test/resources/ssl/provider-core.p12 diff --git a/ids-api/src/main/proto/idscpv2.proto b/ids-api/src/main/proto/idscpv2.proto new file mode 100644 index 000000000..ecf82336d --- /dev/null +++ b/ids-api/src/main/proto/idscpv2.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +option java_package = "de.fhg.aisec.ids.messages"; +option java_outer_classname = "IDSCPv2"; + +//IDSCP message frame, contains a type identifier of the following message and the message +message IdscpMessage { + enum Type { + IDSCP_HELLO = 0; //open a connection by sending an IDSCP_HELLO + IDSCP_CLOSE = 1; //send an IDSCP_CLOSE, that triggers connection close + IDSCP_ERROR = 2; //send an error message + IDSCP_DAT_EXPIRED = 3; //request a ne dynamicAttributeToken + IDSCP_DAT = 4; //send dynamicAttributeToken + IDSCP_RE_RAT = 5; //request a new remote Attestation + IDSCP_RAT_PROVER = 6; //send + IDSCP_RAT_VERIFIER = 7; //send + IDSCP_DATA = 8; //send IDSCP Payload + } + + // Identifies which field is filled in. + Type type = 1; + + // One of the following will be filled in. + oneof message { + IdscpHello idscpHello = 2; + IdscpClose idscpClose = 3; + IdscpError idscpError = 4; + IdscpDatExpired idscpDatExpired = 5; + IdscpDat idscpDat = 6; + IdscpReRat idscpReRat = 7; + IdscpRatProver idscpRatProver = 8; + IdscpRatVerifier idscpRatVerifier = 9; + IdscpData idscpData = 10; + } +} + +//IDSCP messages +message IdscpHello { + int32 version = 1; //IDSCP protocol version + IdscpDat dynamicAttributeToken = 2; //initial dynamicAttributeToken + repeated string supportedRatSuite = 3; //RemoteAttestationCipher prover + repeated string expectedRatSuite = 4; //RemoteAttestationCipher verifier +} + +message IdscpClose { +} + +message IdscpError { + string error_code = 1; + string error_msg = 2; +} + +message IdscpDatExpired { //request new dynamicAttributeToken +} + +message IdscpDat { + bytes token = 1; +} + +message IdscpReRat { //request new remoteAttestation + string cause = 1; //optional +} + +message IdscpRatProver { + bytes data = 1; +} + +message IdscpRatVerifier { + bytes data = 1; +} + +message IdscpData { + bytes data = 1 ; +} diff --git a/idscp2/build.gradle b/idscp2/build.gradle index a781231a9..4aee0a96c 100644 --- a/idscp2/build.gradle +++ b/idscp2/build.gradle @@ -22,5 +22,5 @@ dependencies { testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 - testImplementation group: 'org.mockito', name: 'mockito-all', version: libraryVersions.mockito + testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java deleted file mode 100644 index 264b2f2c2..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/ClientConfiguration.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Client; - -import de.fhg.aisec.ids.idscp2.IDSCPv2Configuration; - -/** - * IDSCPv2 Client Configuration. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class ClientConfiguration extends IDSCPv2Configuration { - - private String hostname = "localhost"; - - public String getHostname() { - return hostname; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java deleted file mode 100644 index 4ee6b8d10..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/IDSCPv2Client.java +++ /dev/null @@ -1,121 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Client; - -import de.fhg.aisec.ids.idscp2.Constants; -import de.fhg.aisec.ids.idscp2.DataAvailableListener; -import de.fhg.aisec.ids.idscp2.InputListenerThread; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.charset.StandardCharsets; - -/** - * An abstract client implementation for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public abstract class IDSCPv2Client implements DataAvailableListener { - private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Client.class); - - protected ClientConfiguration clientConfiguration = null; - protected Socket clientSocket = null; - protected OutputStream out = null; - protected InputStream in = null; - protected InputListenerThread inputListenerThread = null; - - public IDSCPv2Client(){ - - } - - public boolean connect(){ - if (clientSocket == null || clientSocket.isClosed()){ - LOG.error("Client socket is not available"); - return false; - } - - try { - clientSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), - clientConfiguration.getServerPort())); - LOG.info("Client is connected to server " + clientConfiguration.getHostname() - + ":" + clientConfiguration.getServerPort()); - out = clientSocket.getOutputStream(); - in = clientSocket.getInputStream(); - - //set clientSocket timeout to allow safeStop() - clientSocket.setSoTimeout(5000); - - //start receiving listener - inputListenerThread = new InputListenerThread(in); - inputListenerThread.register(this); - inputListenerThread.start(); - LOG.info("Input listener thread was started"); - - } catch (IOException e) { - LOG.error("Connecting client to server failed"); - e.printStackTrace(); - disconnect(false); - return false; - } - return true; - } - - public void disconnect(boolean initialized) { - LOG.info("Disconnecting from server"); - //close listener - if (inputListenerThread != null && inputListenerThread.isAlive()) { - inputListenerThread.safeStop(); - } - - //send goodbye and close sockets - if (clientSocket != null && !clientSocket.isClosed()){ - if (initialized && clientSocket.isConnected()){ - send(Constants.CLIENT_GOODBYE); - } - try { - clientSocket.close(); - } catch (IOException e) { - //e.printStackTrace(); - } - } - } - - public void send(byte[] data){ - if (!isConnected()){ - LOG.error("Client cannot send data because socket is not connected"); - } else { - try { - out.write(data); - out.flush(); - LOG.info("Sent message: " + new String(data)); - } catch (IOException e){ - LOG.error("Client cannot send data"); - e.printStackTrace(); - } - } - } - - public void send(String data){ - send(data.getBytes()); - } - - /* this is called by a listener thread when data were received*/ - public void onMessage(int len, byte[] rawData){ - String data = new String(rawData, 0, len, StandardCharsets.UTF_8); - if (data.equals(Constants.END_OF_STREAM)){ - //End of stream, connection is not available anymore - LOG.info("Client is terminating after server disconnected"); - disconnect(false); - } - //toDo do something with the received data - System.out.println("New data received: " + data); - } - - public boolean isConnected(){ - return clientSocket != null && clientSocket.isConnected(); - } - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java deleted file mode 100644 index 081b1c09c..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Client/TLSClient.java +++ /dev/null @@ -1,120 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Client; - -import de.fhg.aisec.ids.idscp2.Constants; -import de.fhg.aisec.ids.idscp2.InputListenerThread; -import de.fhg.aisec.ids.idscp2.TLSPreConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.*; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; - -/** - * A TLS client implementation for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public class TLSClient extends IDSCPv2Client implements HandshakeCompletedListener{ - private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); - - public TLSClient(ClientConfiguration clientConfiguration){ - this.clientConfiguration = clientConfiguration; - - /* init TLS Client */ - try { - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( - clientConfiguration.getTrustStorePath(), - clientConfiguration.getTrustStorePassword() - ); - - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( - clientConfiguration.getKeyStorePath(), - clientConfiguration.getKeyStorePassword(), - clientConfiguration.getCertAlias(), - clientConfiguration.getKeyStoreKeyType() - ); - - SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); - sslContext.init(myKeyManager, myTrustManager, null); - - SSLSocketFactory socketFactory = sslContext.getSocketFactory(); - - //create server socket - clientSocket = socketFactory.createSocket(); - - SSLSocket sslSocket = (SSLSocket) clientSocket; - SSLParameters sslParameters = sslSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(false); //use server priority order - sslParameters.setNeedClientAuth(true); - sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 - sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher - sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification - sslSocket.setSSLParameters(sslParameters); - LOG.info("TLS Client was initialized successfully"); - - } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ - LOG.error("Init TLS Client failed"); - e.printStackTrace(); - } - } - - @Override - public boolean connect() { - SSLSocket sslSocket = (SSLSocket) clientSocket; - if (sslSocket == null || sslSocket.isClosed()){ - System.out.println("Client socket is not available"); - return false; - } - - try { - sslSocket.connect(new InetSocketAddress(clientConfiguration.getHostname(), - clientConfiguration.getServerPort())); - LOG.info("Client is connected to server " + clientConfiguration.getHostname() - + ":" + clientConfiguration.getServerPort()); - - //set clientSocket timeout to allow safeStop() - clientSocket.setSoTimeout(5000); - - out = clientSocket.getOutputStream(); - in = clientSocket.getInputStream(); - - //add inputListener but start it not before handshake is complete - inputListenerThread = new InputListenerThread(in); - inputListenerThread.register(this); - - //start tls handshake - sslSocket.addHandshakeCompletedListener(this); - LOG.info("Start TLS Handshake"); - sslSocket.startHandshake(); - } catch (SSLHandshakeException e){ - System.out.println("TLS Handshake failed" + e.getMessage()); - disconnect(false); - return false; - } catch (IOException e) { - LOG.error("Connecting TLS client to server failed"); - //e.printStackTrace(); - disconnect(false); - return false; - } - return true; - } - - public SSLSession getSslSession() { - return ((SSLSocket)clientSocket).getSession(); - } - - @Override - public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { - //start receiving listener for IDSCPv2 communication after TLS Handshake was successful - LOG.info("TLS Handshake was successful. Starting input listener thread"); - inputListenerThread.start(); - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java deleted file mode 100644 index 207ffdc0c..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Constants.java +++ /dev/null @@ -1,79 +0,0 @@ -package de.fhg.aisec.ids.idscp2; - -/** - * Global IDSCPv2 protocol constants - * - * @author Leon Beckmann(leon.beckmann@aisec.fraunhofer.de) - */ - -public final class Constants { - - //IDSCPv2 message types - public static final int ATTESTATION_REQUEST_MSG = 0; - public static final int ATTESTATION_RESPONSE_MSG = 1; - public static final int METADATA_REQUEST_MSG = 2; - public static final int METADATA_RESPONSE_MSG = 3; - public static final int PAYLOAD_MSG = 4; - - - //Standard Messages - public static final String CLIENT_GOODBYE = "Client is disconnecting"; - public static final String SERVER_GOODBYE = "Server is disconnecting"; - public static final String END_OF_STREAM = "End of stream"; - - /* TLS specific settings */ - - //socket instances - public static final String TLS_INSTANCE = "TLSv1.2"; - - //enabled protocols - public static final String[] TLS_ENABLED_PROTOCOLS = {TLS_INSTANCE}; - public static final String[] TLS_ENABLED_CIPHER = { - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", - /*"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ - }; - - - private Constants(){}; -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java deleted file mode 100644 index 7efa5e8b3..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/DataAvailableListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.fhg.aisec.ids.idscp2; - -/** - * A Interface for DataAvailableListeners - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public interface DataAvailableListener { - - void onMessage(int len, byte[] bytes); - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java new file mode 100644 index 000000000..d0a7c5f96 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java @@ -0,0 +1,20 @@ +package de.fhg.aisec.ids.idscp2; + +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; + +/** + * An interface for the IDSCPv2Initiator class, that implements a callback function notify the user, a new connection + * was created + * + * Developer API + * + * Methods: + * void onConnect(IDSCPv2Connection) to notify the user, a new connection was created + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface IDSCPv2Initiator { + void newConnectionHandler(IDSCPv2Connection connection); + void errorHandler(String error); + void connectionClosedHandler(String connectionId); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java deleted file mode 100644 index f4f8dc78f..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.fhg.aisec.ids.idscp2; - -/** - * A event source interface for DataAvailableListener pattern - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public interface InputListener { - - void register(DataAvailableListener listener); - - void unregister(DataAvailableListener listener); - - void safeStop(); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java deleted file mode 100644 index 237711cee..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/IDSCPv2Server.java +++ /dev/null @@ -1,65 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.ServerSocket; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; - -/** - * An abstract server implementation for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public abstract class IDSCPv2Server implements ServerNodeSynchronizer { - private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); - - protected ConcurrentHashMap servers = new ConcurrentHashMap<>(); - protected ServerConfiguration serverConfiguration; - protected volatile boolean isRunning = false; - protected ServerSocket serverSocket = null; - - public IDSCPv2Server(ServerConfiguration serverConfiguration){ - this.serverConfiguration = serverConfiguration; - } - - protected boolean start(){ - LOG.info("Starting server"); - return (isRunning = true); - } - - public void stop(){ - LOG.info("Stopping server"); - isRunning = false; - terminateRunningThreads(); - } - - public void close(){ - stop(); - if (serverSocket != null && !serverSocket.isClosed()){ - try { - serverSocket.close(); - } catch (IOException e) { - LOG.error("Could not close server socket"); - e.printStackTrace(); - } - } - terminateRunningThreads(); - } - - private void terminateRunningThreads(){ - servers.forEach((id, serverThread) -> serverThread.safeStop()); - servers.clear(); - } - - public boolean isRunning(){ - return isRunning; - } - - public void unregisterServerOnClose(String connectionId){ - servers.remove(connectionId); - } - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java deleted file mode 100644 index cacdab133..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerConfiguration.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -import de.fhg.aisec.ids.idscp2.IDSCPv2Configuration; - -/** - * IDSCPv2 Server Configuration - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public class ServerConfiguration extends IDSCPv2Configuration { - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java deleted file mode 100644 index 8b5bc652f..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerNodeSynchronizer.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -public interface ServerNodeSynchronizer { - - void unregisterServerOnClose(String connectionId); - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java deleted file mode 100644 index 1a4d663bb..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/ServerThread.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -/** - * A server thread interface for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public interface ServerThread { - void send(byte[] bytes); - void safeStop(); - boolean isConnected(); - void registerListener(ServerNodeSynchronizer serverNodeSynchronizer); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java deleted file mode 100644 index ce5613615..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServer.java +++ /dev/null @@ -1,109 +0,0 @@ -package de.fhg.aisec.ids.idscp2.Server; - -import de.fhg.aisec.ids.idscp2.Constants; -import de.fhg.aisec.ids.idscp2.TLSPreConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.*; -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.security.*; -import java.util.UUID; - -/** - * A TLS server implementation for the IDSCPv2 protocol. - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ - -public class TLSServer extends IDSCPv2Server { - private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); - - public TLSServer(ServerConfiguration serverConfiguration){ - super(serverConfiguration); - - /* init server for TCP/TLS communication */ - try { - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( - serverConfiguration.getTrustStorePath(), - serverConfiguration.getTrustStorePassword() - ); - - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( - serverConfiguration.getKeyStorePath(), - serverConfiguration.getKeyStorePassword(), - serverConfiguration.getCertAlias(), - serverConfiguration.getKeyStoreKeyType() - ); - - // create tls context based on keyManager and trustManager - SSLContext sslContext = SSLContext.getInstance(Constants.TLS_INSTANCE); - sslContext.init(myKeyManager, myTrustManager, null); - SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); - - //create server socket - serverSocket = socketFactory.createServerSocket(serverConfiguration.getServerPort()); - //set timeout for serverSocket.accept() to allow safeStop() - serverSocket.setSoTimeout(5000); - - SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; - SSLParameters sslParameters = sslServerSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite - sslParameters.setNeedClientAuth(true); //client must authenticate - sslParameters.setProtocols(Constants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 - sslParameters.setCipherSuites(Constants.TLS_ENABLED_CIPHER); //only allow strong cipher suite - //toDo uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment - //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification - sslServerSocket.setSSLParameters(sslParameters); - LOG.info("Server was initialized successfully"); - - } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ - LOG.error("Init SSL server socket failed"); - e.printStackTrace(); - } - } - - @Override - public boolean start() { - if (serverSocket == null || serverSocket.isClosed()){ - LOG.error("SSL Server socket is not available"); - return false; - } - - //run server - super.start(); - - SSLSocket sslSocket; - while(isRunning){ - try { - sslSocket = (SSLSocket) serverSocket.accept(); - } catch (SocketTimeoutException e){ - //timeout on serverSocket blocking functions was reached - //in this way we can catch safeStop() function, that makes isRunning false - //without closing the serverSocket, so we can stop and restart the server - //alternative: close serverSocket. But then we cannot reuse it - continue; - } catch (IOException e) { - System.out.println("SSL Server failed"); - e.printStackTrace(); - return false; - } - - //start new server thread - LOG.info("New client has connected. Create new server session"); - String connectionId = UUID.randomUUID().toString(); - TLSServerThread server = new TLSServerThread(sslSocket, connectionId); - server.registerListener(this); - servers.put(connectionId, server); - sslSocket.addHandshakeCompletedListener(server); - server.start(); - } - - return true; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java new file mode 100644 index 000000000..e2e79bffe --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -0,0 +1,21 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; + +/** + * Default DAPS Driver for requesting valid dynamicAttributeToken and verifying DAT + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class DefaultDapsDriver implements DapsDriver { + + @Override + public byte[] getToken() { + return new byte[0]; + } + + @Override + public boolean verifyToken(byte[] dat) { + return false; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java new file mode 100644 index 000000000..63d8c51ba --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java @@ -0,0 +1,11 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; + +/** + * Remote Attestation Prover Driver implementation class for TPM2.0 + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class TPM2ProverImpl implements RatProverDriver { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java new file mode 100644 index 000000000..c67acb75d --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java @@ -0,0 +1,11 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; + +/** + * Remote Attestation Verifier Driver implementation class for TPM2.0 + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class TPM2VerifierImpl implements RatVerifierDriver { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java new file mode 100644 index 000000000..471d7672c --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -0,0 +1,25 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client.TLSClient; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server.TLSServer; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; + + +public class NativeTLSDriver implements SecureChannelDriver { + + @Override + public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { + TLSClient tlsClient = new TLSClient(settings, callback); + tlsClient.connect(settings.getHost(), settings.getServerPort()); + } + + @Override + public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback) { + TLSServer tlsServer = new TLSServer(settings, callback); + tlsServer.start(); + return tlsServer; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java new file mode 100644 index 000000000..f9662adcf --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java @@ -0,0 +1,117 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; + +/** + * TLS Constants + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public final class TlsConstants { + + public static final String END_OF_STREAM = "End of stream"; + + /* TLS specific settings */ + + //socket instances + public static final String TLS_INSTANCE = "TLSv1.3"; + + //enabled protocols + public static final String[] TLS_ENABLED_PROTOCOLS = {TLS_INSTANCE}; + + //enabled ciphers (only uncommented ciphers are activated) + public static final String[] TLS_ENABLED_CIPHER_TLS12 = { + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + /*"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ + }; + + // not all of the enabled ciphers are supported by openssl yet + public static final String[] TLS_ENABLED_CIPHER_TLS13 = { + //"TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", + /*"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",*/ + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", + /*"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ + }; + + private TlsConstants() {}; +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java new file mode 100644 index 000000000..1e8c035d6 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -0,0 +1,10 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; + +/** + * An interface for DataAvailableListeners, who will be notified when new data were received + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface DataAvailableListener { + void onMessage(int len, byte[] rawData); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java new file mode 100644 index 000000000..b3826bad2 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; + +/** + * An interface for an InputListenerThread, that allows DataAvailableListener registration and safe stop + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface InputListener { + + void register(DataAvailableListener listener); + void safeStop(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java similarity index 72% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 4046d7e5c..83a808c7d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -1,4 +1,6 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; import java.io.IOException; import java.io.InputStream; @@ -6,11 +8,16 @@ import java.util.ArrayList; /** - * A simple Listener thread that listens to an input stream and notifies all listeners when data was received + * A simple Listener thread that listens to an input stream and notifies all listeners when new data were received + * + * API: + * - run() to start the listener thread + * - register(DataAvailableListener) to register a new DataAvailableListener who will be notified when receiving data + * - safeStop() to stop the listener thread * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class InputListenerThread extends Thread implements InputListener{ +public class InputListenerThread extends Thread implements InputListener { private InputStream in; private ArrayList listeners = new ArrayList<>(); @@ -24,9 +31,9 @@ public void run(){ byte[] buf = new byte[2048]; while (running){ try { - int len = in.read(buf, 0, buf.length - 1); + int len = in.read(buf, 0, buf.length); if (0 > len) { - notifyListeners(Constants.END_OF_STREAM.length(), Constants.END_OF_STREAM.getBytes()); + notifyListeners(TlsConstants.END_OF_STREAM.length(), TlsConstants.END_OF_STREAM.getBytes()); running = false; //terminate } else { notifyListeners(len, buf); @@ -48,11 +55,6 @@ public void register(DataAvailableListener listener) { listeners.add(listener); } - @Override - public void unregister(DataAvailableListener listener) { - listeners.remove(listener); - } - private void notifyListeners(int len, byte[] bytes) { for (DataAvailableListener listener : listeners){ listener.onMessage(len, bytes); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java new file mode 100644 index 000000000..3bd6bd8a7 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -0,0 +1,216 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores.TLSPreConfiguration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + + /** + * A TLS Client that notifies an IDSCPv2Configuration when a secure channel was created and the TLS handshake is done + * The client is notified from an InputListenerThread when new data are available and transfer them to the + * SecureChannelListener + * + * Developer API + * + * constructors: + * TLSClient(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket and all TLS Security configurations like + * sslParameters (protocol, cipher, ..), trustStore, keyStore + * + * Methods: + * connect(String host, int port) connect the client asynchronous to the server and starts the TLS handshake + * + * close() disconnects the client + * + * setConnectionId(ConnectionId) set the internal connectionId, which is used for notifying the IDSCPv2Configuration + * when the server quits the connection + * + * handshakeCompleted() create a secureChannel, including this client; start inputListenerThread and transfer + * the secureChannel to the IDSCPv2Configuration + * + * send(byte[] data) send data to the server + * + * onMessage(int len, byte[] rawData) is a callback function for the InputListenerThread, that is called when new + * data are available. Transfer them to the SecureChannelListener + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ + +public class TLSClient implements HandshakeCompletedListener, DataAvailableListener, SecureChannelEndpoint { + private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); + + private Socket clientSocket; + private OutputStream out; + private InputListenerThread inputListenerThread; + private SecureChannelListener listener; + private IDSCPv2Callback callback; + private String connectionId = null; + + public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback){ + this.callback = callback; + /* init TLS Client */ + try { + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + clientSettings.getTrustStorePath(), + clientSettings.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + clientSettings.getKeyStorePath(), + clientSettings.getKeyStorePassword(), + clientSettings.getCertAlias(), + clientSettings.getKeyStoreKeyType() + ); + + SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + + SSLSocketFactory socketFactory = sslContext.getSocketFactory(); + + //create server socket + clientSocket = socketFactory.createSocket(); + + SSLSocket sslSocket = (SSLSocket) clientSocket; + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(false); //use server priority order + sslParameters.setNeedClientAuth(true); + sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 + sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification + sslSocket.setSSLParameters(sslParameters); + LOG.info("TLS Client was initialized successfully"); + + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ + LOG.error("Init TLS Client failed"); + e.printStackTrace(); + } + } + + + public void connect(String hostname, int port){ + SSLSocket sslSocket = (SSLSocket) clientSocket; + if (sslSocket == null || sslSocket.isClosed()){ + System.out.println("Client socket is not available"); + callback.secureChannelConnectHandler(null); + return; + } + + try { + sslSocket.connect(new InetSocketAddress(hostname, + port)); + LOG.info("Client is connected to server {}:{}", hostname, port); + + //set clientSocket timeout to allow safeStop() + clientSocket.setSoTimeout(5000); + + out = clientSocket.getOutputStream(); + + //add inputListener but start it not before handshake is complete + inputListenerThread = new InputListenerThread(clientSocket.getInputStream()); + inputListenerThread.register(this); + + //start tls handshake + sslSocket.addHandshakeCompletedListener(this); + LOG.info("Start TLS Handshake"); + sslSocket.startHandshake(); + } catch (SSLHandshakeException | SSLProtocolException e){ + LOG.error("TLS Handshake failed: {}", e.getMessage()); + disconnect(); + callback.secureChannelConnectHandler(null); + } catch (IOException e) { + LOG.error("Connecting TLS client to server failed " + e.getMessage()); + disconnect(); + callback.secureChannelConnectHandler(null); + } + } + + private void disconnect(){ + LOG.info("Disconnecting from server"); + //close listener + if (inputListenerThread != null && inputListenerThread.isAlive()) { + inputListenerThread.safeStop(); + } + + if (clientSocket != null && !clientSocket.isClosed()){ + try { + clientSocket.close(); + } catch (IOException e) { + //e.printStackTrace(); + } + } + } + + @Override + public void setConnectionId(String connectionId){ + this.connectionId = connectionId; + } + + @Override + public void close() { + disconnect(); + } + + public void send(byte[] data){ + if (!isConnected()){ + LOG.error("Client cannot send data because socket is not connected"); + } else { + try { + out.write(data); + out.flush(); + LOG.info("Send message: {}", new String(data)); + } catch (IOException e){ + LOG.error("Client cannot send data"); + e.printStackTrace(); + } + } + } + + public boolean isConnected(){ + return clientSocket != null && clientSocket.isConnected(); + } + + public SSLSession getSslSession() { + return ((SSLSocket)clientSocket).getSession(); + } + + @Override + public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { + //start receiving listener after TLS Handshake was successful + LOG.info("TLS Handshake was successful. Starting input listener thread"); + SecureChannel secureChannel = new SecureChannel(this); + this.listener = secureChannel; + inputListenerThread.start(); + callback.secureChannelConnectHandler(secureChannel); + } + + @Override + public void onMessage(int len, byte[] rawData) { + byte[] data = new byte[len]; + System.arraycopy(rawData, 0, data, 0, len); + if ((new String(data, StandardCharsets.UTF_8)).equals(TlsConstants.END_OF_STREAM)){ + //End of stream, connection is not available anymore + LOG.info("Client is terminating after server disconnected"); + disconnect(); + callback.connectionClosedHandler(this.connectionId); + } else { + listener.onMessage(data); + } + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java similarity index 66% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java index 86ea63919..f838cf09e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java @@ -1,16 +1,16 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedKeyManager; -import java.lang.reflect.Array; import java.net.Socket; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.HashMap; /** * A custom X590ExtendedKeyManager, that allows to choose a TrustStore entry by a given certificate alias and @@ -25,7 +25,14 @@ public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ private final String keyType; private final X509ExtendedKeyManager delegate; - public CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate){ + // server and client aliases are cached in a private context (in entryCacheMap) by the X509ExtendedKeyManager + // implementation. Therefore, getServerAliases() / getClientAliases() returns only uncached aliases since the + // update on java 11. As we have to check in chooseClientAliases() and chooseServerAlias() if the alias exists in + // the keystore and we cannot access the cached aliases without an overwritten X509KeyManagerImpl instance, we will + // also cache the aliases and its properties in the following HashMap. + private HashMap cachedAliases = new HashMap<>(); + + CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate){ super(); this.certAlias = alias; this.keyType = keyType; @@ -34,7 +41,10 @@ public CustomX509ExtendedKeyManager(String alias, String keyType, final X509Exte @Override public String[] getClientAliases(String s, Principal[] principals) { - return delegate.getClientAliases(s, principals); + String[] clientAliases = delegate.getClientAliases(s, principals); + for (String alias : clientAliases) + cachedAliases.putIfAbsent(alias, new CachedAliasValue(s, principals)); + return clientAliases; } @Override @@ -42,7 +52,9 @@ public String[] getClientAliases(String s, Principal[] principals) { called only by client in TLS handshake */ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) { if (Arrays.asList(keyTypes).contains(this.keyType)){ - if (Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { + if ((cachedAliases.containsKey(this.certAlias) && + cachedAliases.get(this.certAlias).match(keyType, issuers)) + || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { LOG.info("CertificateAlias is {}", this.certAlias); return this.certAlias; } else { @@ -59,7 +71,10 @@ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket s @Override public String[] getServerAliases(String s, Principal[] principals) { - return delegate.getServerAliases(s, principals); + String[] serverAliases = delegate.getServerAliases(s, principals); + for (String alias : serverAliases) + cachedAliases.putIfAbsent(alias, new CachedAliasValue(s, principals)); + return serverAliases; } @Override @@ -67,7 +82,8 @@ public String[] getServerAliases(String s, Principal[] principals) { called only by server in TLS handshake*/ public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { if (keyType.equals(this.keyType)){ - if (Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { + if ((cachedAliases.containsKey(certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) + || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { LOG.info("CertificateAlias is {}", this.certAlias); return this.certAlias; } else { @@ -118,4 +134,18 @@ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSL public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine sslEngine){ return delegate.chooseEngineServerAlias(keyType, issuers, sslEngine); } + + private class CachedAliasValue { + private String keyType; + private Principal[] issuers; + + CachedAliasValue(String keyType, Principal[] issuers){ + this.keyType = keyType; + this.issuers = issuers; + } + + boolean match(String keyType, Principal[] principals){ + return this.keyType.equals(keyType) && (principals == null /* || //FIXME check issuers */); + } + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java new file mode 100644 index 000000000..725ae2361 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java @@ -0,0 +1,79 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.X509ExtendedTrustManager; +import java.net.Socket; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** + * currently not in use, we will use the https hostname verification instead + * + * A custom X509ExtendedTrustManager for hostname verification and algorithm constraints, + * which is an application protocol task and avoids Man-In-The-Middle Attacks + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class CustomX509ExtendedTrustManager extends X509ExtendedTrustManager { + /* + * verifying that the certificate itself can be trusted (RFC 3280/5280) and verifying the identity in the certificate (RFC 6125, or RFC 2818 for HTTPS) + * https://tersesystems.com/blog/2014/03/23/fixing-hostname-verification/ + * https://tools.ietf.org/html/rfc6125 + * https://tools.ietf.org/search/rfc6125 + * + * + * sslParams.setEndpointIdentificationAlgorithm("HTTPS"); //makes identity verification in the ssl context + * + * + * If the socket parameter is an instance of SSLSocket, and the endpoint identification algorithm of the + * SSLParameters is non-empty, to prevent man-in-the-middle attacks, the address that the socket connected to + * should be checked against the peer's identity presented in the end-entity X509 certificate, as specified in + * the endpoint identification algorithm. + * + * + * If the socket parameter is an instance of SSLSocket, and the algorithm constraints of the SSLParameters is + * non-null, for every certificate in the certification path, fields such as subject public key, the signature + * algorithm, key usage, extended key usage, etc. need to conform to the algorithm constraints in place on this + * socket.*/ + + private X509ExtendedTrustManager delegate; + + public CustomX509ExtendedTrustManager(X509ExtendedTrustManager delegate){ + this.delegate = delegate; + } + + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s, socket); + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s, socket); + } + + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s, sslEngine); + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s, sslEngine); + } + + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + delegate.checkClientTrusted(x509Certificates, s); + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + delegate.checkServerTrusted(x509Certificates, s); + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return delegate.getAcceptedIssuers(); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java similarity index 95% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java index 525bd2f90..3ce92fca5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; import javax.net.ssl.*; import java.io.IOException; @@ -44,8 +44,8 @@ public static TrustManager[] getX509ExtTrustManager( /* set up TrustManager config */ //allow only X509 Authentication if (myTrustManager.length == 1 && myTrustManager[0] instanceof X509ExtendedTrustManager) { - //toDo hostname verification and algorithm constraints - + //toDo algorithm constraints + //toDO hostname verification is currently done by using https identification protocol return myTrustManager; } else { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(myTrustManager)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java new file mode 100644 index 000000000..9bf576e23 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -0,0 +1,147 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores.TLSPreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.SocketTimeoutException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +/** + * A TLS Server that listens on a given port from the IDSCPv2Settings and create new TLSServerThreads for incoming + * connections + * + * Developer API + * + * constructors: + * TLSServer(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket and all TLS Security configurations like + * sslParameters (protocol, cipher, ..), trustStore, keyStore + * + * Methods: + * run() + * safeStop() + * isRunning() + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class TLSServer extends Thread implements SecureServer { + private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); + + private volatile boolean isRunning = false; + private ServerSocket serverSocket = null; + private IDSCPv2Callback callback; + + public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback){ + this.callback = callback; + + /* init server for TCP/TLS communication */ + try { + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + serverSettings.getTrustStorePath(), + serverSettings.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + serverSettings.getKeyStorePath(), + serverSettings.getKeyStorePassword(), + serverSettings.getCertAlias(), + serverSettings.getKeyStoreKeyType() + ); + + // create tls context based on keyManager and trustManager + SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); + + //create server socket + serverSocket = socketFactory.createServerSocket(serverSettings.getServerPort()); + //set timeout for serverSocket.accept() to allow safeStop() + serverSocket.setSoTimeout(5000); + + SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; + SSLParameters sslParameters = sslServerSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite + sslParameters.setNeedClientAuth(true); //client must authenticate + sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 + sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite + //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment + //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification + sslServerSocket.setSSLParameters(sslParameters); + LOG.info("Server was initialized successfully"); + + } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ + LOG.error("Init SSL server socket failed"); + e.printStackTrace(); + } + + } + + @Override + public void run(){ + LOG.info("Starting server"); + + if (serverSocket == null || serverSocket.isClosed()){ + LOG.error("TLS Server socket is not available"); + return; + } + + SSLSocket sslSocket; + isRunning = true; + LOG.info("Server is running"); + while(isRunning){ + try { + sslSocket = (SSLSocket) serverSocket.accept(); + } catch (SocketTimeoutException e){ + //timeout on serverSocket blocking functions was reached + //in this way we can catch safeStop() function, that makes isRunning false + //without closing the serverSocket, so we can stop and restart the server + //alternative: close serverSocket. But then we cannot reuse it + continue; + } catch (IOException e) { + System.out.println("TLS Server failed"); + e.printStackTrace(); + isRunning = false; + return; + } + + //start new server thread + LOG.info("New TLS client has connected. Create new server session"); + TLSServerThread server = new TLSServerThread(sslSocket, this.callback); + sslSocket.addHandshakeCompletedListener(server); + server.start(); + } + + if (serverSocket != null && !serverSocket.isClosed()){ + try { + serverSocket.close(); + } catch (IOException e) { + LOG.error("Could not close TLS server socket"); + e.printStackTrace(); + } + } + } + + @Override + public void safeStop(){ + LOG.info("Stopping server"); + isRunning = false; + } + + @Override + public boolean isRunning(){ + return isRunning; + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java similarity index 51% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 5dac2ac76..0399dceb4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -1,6 +1,9 @@ -package de.fhg.aisec.ids.idscp2.Server; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; -import de.fhg.aisec.ids.idscp2.Constants; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,29 +15,49 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.SocketTimeoutException; -import java.nio.charset.StandardCharsets; +import java.util.concurrent.CountDownLatch; /** - * A TLS server thread implementation for the IDSCPv2 protocol. + * A TLSServerThread that notifies an IDSCPv2Config when a secure channel was created and the TLS handshake is done + * When new data are available the serverThread transfers them to the SecureChannelListener + * + * Developer API + * + * constructors: + * TLSServerThread(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket + * + * Methods: + * run() runs the serverThread and starts listening for new data + * + * close() disconnects the serverThread + * + * setConnectionId(ConnectionId) set the internal connectionId, which is used for notifying the IDSCPv2Configuration + * when the client quits the connection + * + * handshakeCompleted() create a secureChannel, including this serverThread and provides it to the IDSCPv2Config + * + * send(byte[] data) send data to the client + * + * onMessage(int len, byte[] rawData) is called when new data are available. Transfer them to the SecureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ - -public class TLSServerThread extends Thread implements ServerThread, HandshakeCompletedListener { +public class TLSServerThread extends Thread implements HandshakeCompletedListener, SecureChannelEndpoint { private static final Logger LOG = LoggerFactory.getLogger(TLSServerThread.class); private SSLSocket sslSocket; private volatile boolean running = true; private InputStream in; private OutputStream out; - private boolean tlsHandshakeCompleted = false; - private boolean sendServerGoodbye = true; - private ServerNodeSynchronizer serverNodeSynchronizer = null; - private String connectionId; //unique server - client connection id, that identifies this serverThread + private String connectionId; + private SecureChannelListener listener = null; + private IDSCPv2Callback callback; + private CountDownLatch listenerLatch = new CountDownLatch(1); - TLSServerThread(SSLSocket sslSocket, String connectionId){ + + TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback callback){ this.sslSocket = sslSocket; - this.connectionId = connectionId; + this.callback = callback; try { //set timout for blocking read @@ -47,6 +70,11 @@ public class TLSServerThread extends Thread implements ServerThread, HandshakeCo } } + @Override + public void setConnectionId(String connectionId){ + this.connectionId = connectionId; + } + @Override public void run(){ //wait for new data while running @@ -54,9 +82,9 @@ public void run(){ while (running){ try { - int len = in.read(buf, 0, buf.length - 1); + int len = in.read(buf, 0, buf.length); if (0 > len) { - onMessage(Constants.END_OF_STREAM.length(), Constants.END_OF_STREAM.getBytes()); + //onMessage(TlsConstants.END_OF_STREAM.length(), TlsConstants.END_OF_STREAM.getBytes()); running = false; } else { onMessage(len, buf); @@ -75,22 +103,17 @@ public void run(){ running = false; } } + callback.connectionClosedHandler(this.connectionId); + LOG.info("ServerThread is terminating"); try { - if (sendServerGoodbye) - send(Constants.SERVER_GOODBYE); out.close(); in.close(); sslSocket.close(); } catch (IOException e) { e.printStackTrace(); } - - //unregister from main server - if (this.serverNodeSynchronizer != null) - this.serverNodeSynchronizer.unregisterServerOnClose(this.connectionId); } - @Override public void send(byte[] data) { if (!isConnected()){ LOG.error("Server cannot send data because socket is not connected"); @@ -106,41 +129,36 @@ public void send(byte[] data) { } } - public void send(String data){ - send(data.getBytes()); + @Override + public void close() { + safeStop(); } - public void onMessage(int len, byte[] rawData) { - String data = new String(rawData, 0, len, StandardCharsets.UTF_8); - if (data.equals(Constants.END_OF_STREAM) || - data.equals(Constants.CLIENT_GOODBYE)){ - //End of stream or client goodbye, connection is no longer available - running = false; //terminate server - LOG.info("Server is terminating after client disconnect"); - sendServerGoodbye = false; - } else { - //toDo do something with the received data - System.out.println("New data received: " + data); + public void onMessage(int len, byte[] rawData) { + byte[] data = new byte[len]; + System.arraycopy(rawData, 0, data, 0, len); + try{ + listenerLatch.await(); + this.listener.onMessage(data); + } catch (InterruptedException e){ + e.printStackTrace(); } } - public void safeStop(){ + private void safeStop(){ running = false; } - @Override public boolean isConnected() { return (sslSocket != null && sslSocket.isConnected()); } - @Override - public void registerListener(ServerNodeSynchronizer serverNodeSynchronizer) { - this.serverNodeSynchronizer = serverNodeSynchronizer; - } - @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { - tlsHandshakeCompleted = true; LOG.info("TLS handshake was successful"); + SecureChannel secureChannel = new SecureChannel(this); + this.listener = secureChannel; + listenerLatch.countDown(); + callback.secureChannelListenHandler(secureChannel); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java new file mode 100644 index 000000000..ebc2c2c47 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +/** + * An interface for the DAPS driver, which is used to verify and request dynamicAttributeTokens + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface DapsDriver { + + byte[] getToken(); + boolean verifyToken(byte[] dat); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java new file mode 100644 index 000000000..eb410c0dc --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -0,0 +1,10 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +/** + * An interface for the remote attestation prover driver that is used for proving the current state by RAT mechanism + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface RatProverDriver { + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java new file mode 100644 index 000000000..aabc88d10 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -0,0 +1,9 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +/** + * An interface for the remote attestation verifier driver that is used for verifying provers system sate + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface RatVerifierDriver { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java new file mode 100644 index 000000000..1d4535d23 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -0,0 +1,9 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; + +public interface SecureChannelDriver { + void connect(IDSCPv2Settings settings, IDSCPv2Callback callback); + SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java new file mode 100644 index 000000000..7e893a04a --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java @@ -0,0 +1,15 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +/** + * + * + * Developer API + * + * Methods: + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public interface SecureServer { + void safeStop(); + boolean isRunning(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java similarity index 64% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java index 315182e33..e16824f26 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Exception.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java @@ -1,5 +1,10 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.error; +/** + * IDSCPv2 Exception + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class IDSCPv2Exception extends RuntimeException{ public IDSCPv2Exception(String message) { super(message); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java new file mode 100644 index 000000000..19cc9cad5 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -0,0 +1,60 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpClose; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; + +/** + * The IDSCPv2 Connection class is the entry point for the IDSCPv2 protocol. It runs a peer (client or server) and + * establishes a secure state by building a secure transfer channel, verifies the dynamicAttributeToken and RAT + * + * Developer API: + * + * Constructors: + * IDSCPv2Connection(SecureChannel sc, String connectionID) + * + * Methods: + * void close() to close an IDSCP connection + * void send(IdscpMessage) to send an idscp message to the other idscp endpoint + * void onMessage() to receive an asynchronous message from the other idscp endpoint + * boolean isConnected() to check if the idscp connection is still open + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class IDSCPv2Connection implements IdscpMsgListener { + + private SecureChannel secureChannel; + private String connectionId; + + public IDSCPv2Connection(SecureChannel secureChannel, String connectionId){ + this.secureChannel = secureChannel; + this.connectionId = connectionId; + secureChannel.setEndpointConnectionId(connectionId); + } + + public void close() { + IdscpMessage msg = IdscpMessage.newBuilder() + .setType(IdscpMessage.Type.IDSCP_CLOSE) + .setIdscpClose(IdscpClose.newBuilder().build() + ).build(); + send(msg); + secureChannel.close(); + } + + public void send(IdscpMessage msg) { + secureChannel.send(msg); + } + + @Override + public void onMessage(IdscpMessage msg) { + System.out.println("Received new IDSCP Message: " + msg.toString()); + } + + public boolean isConnected() { + return secureChannel.isConnected(); + } + + public String getConnectionId() { + return connectionId; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java new file mode 100644 index 000000000..37a9c9502 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java @@ -0,0 +1,10 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +/** + * Global IDSCPv2 protocol constants + * + * @author Leon Beckmann(leon.beckmann@aisec.fraunhofer.de) + */ +public final class IdscpConstants { + private IdscpConstants(){}; +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java new file mode 100644 index 000000000..a3a2a0b22 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java @@ -0,0 +1,7 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; + +public interface IdscpMsgListener { + void onMessage(IdscpMessage message); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java similarity index 81% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index bffae6d66..5a05122da 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -1,11 +1,10 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.idscp_core.configuration; /** * Attestation configuration class, containing attestation suite for supported / expected attestation types * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ - public class AttestationConfig { public AttestationConfig(){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java new file mode 100644 index 000000000..8006525bb --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java @@ -0,0 +1,9 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.configuration; + +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; + +public interface IDSCPv2Callback { + void secureChannelConnectHandler(SecureChannel secureChannel); + void secureChannelListenHandler(SecureChannel secureChannel); + void connectionClosedHandler(String connectionId); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java new file mode 100644 index 000000000..4ee926427 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -0,0 +1,85 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.configuration; + +import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; + +import java.util.UUID; + +/** + * IDSCPv2Configuration Class, provides IDSCPv2 API to the User (IDSCPv2Initiator) + * + * Developer API + * + * Methods: + * void onConnect(IDSCPv2Connection) to notify the user, a new connection was created + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class IDSCPv2Configuration implements IDSCPv2Callback { + + private IDSCPv2Initiator user; + private DapsDriver dapsDriver; + private RatProverDriver ratProverDriver; + private RatVerifierDriver ratVerifierDriver; + private SecureChannelDriver secureChannelDriver; + + + public IDSCPv2Configuration(IDSCPv2Initiator initiator, + DapsDriver dapsDriver, + RatVerifierDriver ratVerifierDriver, + RatProverDriver ratProverDriver, + SecureChannelDriver secureChannelDriver){ + this.user = initiator; + this.dapsDriver = dapsDriver; + this.ratVerifierDriver = ratVerifierDriver; + this.ratProverDriver = ratProverDriver; + this.secureChannelDriver = secureChannelDriver; + } + + public void connect(IDSCPv2Settings settings){ + secureChannelDriver.connect(settings, this); + } + + public SecureServer listen(IDSCPv2Settings settings){ + return secureChannelDriver.listen(settings, this); + } + + @Override + public void secureChannelConnectHandler(SecureChannel secureChannel) { + if (secureChannel == null){ + user.errorHandler("Creating Secure channel failed. Cannot create secure Channel"); + } else { + + //toDo verify security properties + //toDo RAT + + //create new IDSCPv2Connection + String connectionId = UUID.randomUUID().toString(); + IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); + secureChannel.registerMessageListener(newConnection); + user.newConnectionHandler(newConnection); + } + } + + @Override + public void secureChannelListenHandler(SecureChannel secureChannel) { + if (secureChannel != null){ + + //toDo verify security properties + //toDo RAT + + //create new IDSCPv2Connection + String connectionId = UUID.randomUUID().toString(); + IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); + secureChannel.registerMessageListener(newConnection); + user.newConnectionHandler(newConnection); + } + } + + @Override + public void connectionClosedHandler(String connectionId) { + user.connectionClosedHandler(connectionId); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java similarity index 79% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index e4f9f7660..7de785e0d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -1,9 +1,15 @@ -package de.fhg.aisec.ids.idscp2; +package de.fhg.aisec.ids.idscp2.idscp_core.configuration; -public abstract class IDSCPv2Configuration { - public static final int DEFAULT_SERVER_PORT = 8080; +/** + * IDSCPv2 configuration class, containing information about keyStore and TrustStores, Attestation Types + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class IDSCPv2Settings { + public static final int DEFAULT_SERVER_PORT = 8081; private int serverPort = DEFAULT_SERVER_PORT; + private String host = "localhost"; private String trustStorePath = null; private String trustStorePassword = "password"; private String keyStorePath = null; @@ -13,7 +19,6 @@ public abstract class IDSCPv2Configuration { private AttestationConfig supportedAttestation = null; private AttestationConfig expectedAttestation = null; - public AttestationConfig getExpectedAttestation() { return expectedAttestation; } @@ -73,4 +78,12 @@ public void setTrustStorePassword(String trustStorePassword) { public void setKeyStorePassword(String keyStorePassword) { this.keyStorePassword = keyStorePassword; } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java new file mode 100644 index 000000000..ba1387f29 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -0,0 +1,63 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; + +import com.google.protobuf.InvalidProtocolBufferException; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; + +import java.util.Arrays; + +/** + * An interface for the secureChannel (e.g. TLS), which is the secure underlying basis of the IDSCPv2 protocol + * + * Developer API + * + * Constructors depends on the implementation + * + * Methods: + * void close() to close the secureChannel to the other secure endpoint + * void send(IDSCPv2Message) to send an IDSCPv2Message as bytes via the secure channel + * void onMessage(byte[] data) to receive new bytes via the secure channel + * boolean isConnected() to check if the secure channel is still open + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class SecureChannel implements SecureChannelListener { + + private SecureChannelEndpoint endpoint; + private IdscpMsgListener listener = null; + + public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ + this.endpoint = secureChannelEndpoint; + } + + public void close(){ + endpoint.close(); + } + + public void send(IdscpMessage msg){ + endpoint.send(msg.toByteArray()); + } + + @Override + public void onMessage(byte[] data){ + System.out.println(Arrays.toString(data)); + try { + IdscpMessage message = IdscpMessage.parseFrom(data); + listener.onMessage(message); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + + public boolean isConnected(){ + return endpoint.isConnected(); + } + + public void registerMessageListener(IdscpMsgListener listener){ + this.listener = listener; + } + + public void setEndpointConnectionId(String id){ + this.endpoint.setConnectionId(id); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java new file mode 100644 index 000000000..83e08bcba --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -0,0 +1,10 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; + + +public interface SecureChannelEndpoint { + void close(); + void onMessage(int len, byte[] bytes); + void send(byte[] bytes); + boolean isConnected(); + void setConnectionId(String id); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java new file mode 100644 index 000000000..8ad5218ab --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java @@ -0,0 +1,5 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; + +public interface SecureChannelListener { + void onMessage(byte[] data); +} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java new file mode 100644 index 000000000..d00d0d06a --- /dev/null +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -0,0 +1,38 @@ +import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; + +import java.util.concurrent.ConcurrentHashMap; + +public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { + + private ConcurrentHashMap connections = new ConcurrentHashMap<>(); + + public void init(IDSCPv2Settings settings){ + SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, + null, null, null, secureChannelDriver); + clientConfig.connect(settings); + } + + + @Override + public void newConnectionHandler(IDSCPv2Connection connection) { + this.connections.put(connection.getConnectionId(), connection); + connection.close(); + } + + @Override + public void errorHandler(String error) { + System.out.println(error); + } + + @Override + public void connectionClosedHandler(String connectionId) { + System.out.println("Connection closed"); + connections.remove(connectionId); + } +} diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java new file mode 100644 index 000000000..eb76df665 --- /dev/null +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -0,0 +1,47 @@ +import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; + +import java.util.concurrent.ConcurrentHashMap; + + +public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { + + private ConcurrentHashMap connections = new ConcurrentHashMap<>(); + private SecureServer secureServer = null; + + + public void init(IDSCPv2Settings serverSettings) { + SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, + null,null,null,secureChannelDriver); + secureServer = idscpServerConfig.listen(serverSettings); + //secureServer.safeStop(); + try { + Thread.sleep(300000); //run server for 5 minutes + } catch (Exception e){ + + } + secureServer.safeStop(); + } + + @Override + public void newConnectionHandler(IDSCPv2Connection connection) { + connections.put(connection.getConnectionId(), connection); + } + + @Override + public void errorHandler(String error) { + + } + + @Override + public void connectionClosedHandler(String connectionId) { + System.out.println("Connection closed"); + connections.remove(connectionId); + } +} diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java index c2902a68d..0be272085 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/test/java/RunTLSClient.java @@ -1,23 +1,18 @@ -import de.fhg.aisec.ids.idscp2.Client.ClientConfiguration; -import de.fhg.aisec.ids.idscp2.Client.TLSClient; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; + public class RunTLSClient { public static void main(String[] args){ - //start client - ClientConfiguration clientConfiguration = new ClientConfiguration(); - clientConfiguration.setKeyStorePath(RunTLSClient.class.getClassLoader(). - getResource("jsse/aisecconnector2-keystore.jks").getPath()); - clientConfiguration.setTrustStorePath(RunTLSClient.class.getClassLoader(). - getResource("jsse/client-truststore_new.jks").getPath()); - TLSClient tlsClient = new TLSClient(clientConfiguration); - if (!tlsClient.connect()) - return; + IDSCPv2Settings settings = new IDSCPv2Settings(); + settings.setKeyStorePath(RunTLSClient.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()); + settings.setTrustStorePath(RunTLSClient.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()); - tlsClient.send("hi, how are u"); + IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); + initiator.init(settings); - tlsClient.disconnect(true); } - } diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/test/java/RunTLSServer.java index 1f2001b62..8265950ff 100644 --- a/idscp2/src/test/java/RunTLSServer.java +++ b/idscp2/src/test/java/RunTLSServer.java @@ -1,17 +1,16 @@ -import de.fhg.aisec.ids.idscp2.Server.ServerConfiguration; -import de.fhg.aisec.ids.idscp2.Server.TLSServer; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -public class RunTLSServer { +public class RunTLSServer{ public static void main(String[] argv){ - ServerConfiguration serverConfiguration = new ServerConfiguration(); - serverConfiguration.setKeyStorePath(RunTLSServer.class.getClassLoader(). - getResource("jsse/aisecconnector2-keystore.jks").getPath()); - serverConfiguration.setTrustStorePath(RunTLSServer.class.getClassLoader(). - getResource("jsse/client-truststore_new.jks").getPath()); - TLSServer tlsServer = new TLSServer(serverConfiguration); - tlsServer.start(); - tlsServer.close(); + IDSCPv2Settings settings = new IDSCPv2Settings(); + settings.setKeyStorePath(RunTLSServer.class.getClassLoader(). + getResource("ssl/aisecconnector2-keystore.jks").getPath()); + settings.setTrustStorePath(RunTLSServer.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()); + + IDSCPv2ServerInitiator initiator = new IDSCPv2ServerInitiator(); + initiator.init(settings); } } diff --git a/idscp2/src/test/resources/jsse/aisecconnector1-keystore.jks b/idscp2/src/test/resources/ssl/aisecconnector1-keystore.jks similarity index 100% rename from idscp2/src/test/resources/jsse/aisecconnector1-keystore.jks rename to idscp2/src/test/resources/ssl/aisecconnector1-keystore.jks diff --git a/idscp2/src/test/resources/jsse/aisecconnector2-keystore.jks b/idscp2/src/test/resources/ssl/aisecconnector2-keystore.jks similarity index 100% rename from idscp2/src/test/resources/jsse/aisecconnector2-keystore.jks rename to idscp2/src/test/resources/ssl/aisecconnector2-keystore.jks diff --git a/idscp2/src/test/resources/jsse/client-truststore_new.jks b/idscp2/src/test/resources/ssl/client-truststore_new.jks similarity index 100% rename from idscp2/src/test/resources/jsse/client-truststore_new.jks rename to idscp2/src/test/resources/ssl/client-truststore_new.jks diff --git a/idscp2/src/test/resources/ssl/consumer-core-keystore.jks b/idscp2/src/test/resources/ssl/consumer-core-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..2954091c5335e34036ec818d63bf9cd08a9651ea GIT binary patch literal 2441 zcma)7c{r497oTSqWNf`7M#z?JnDIP}ZDzDslTvn5sKHF5n910RP!k$^%SRHT##Y0d zq-04+yojQr=(UYD!dteA_(tz?y?=ave1DwlI=^%7`<(ln>vx~CGPN=VgTde;0e%Vq zi8R(9uGIrD7zzNn$RD7Ln52OifCO;x^#Fi^A-TwpBk@C$CalK(=8^p5DG%fjO-uY_ zRG_kIIpJ~%=7%SmU!7!>a*_1PdP(Kol?+;5h%gpYmTQ8~ub-xz`$%!~GI0X)XLT>zCXk)`NYBu=&Pb(HgXqODW4;;@M& zo>h82RP&fHPU#lF>@#M&6wIhyiXm-}WcAEECWR{hRRk*mb8CFm! zKjnTKL11`cn++dD6pkO*{rq_8lwx>H0SY%6v4Gq)scGB&{nm?-Z_+b&3C<r5#5{japgh_K|4KQFO?o*J)0;F?TAX#gUPG= z4aBCQ+nyC3DDsA&Bc7_eY+OzAg!MIf-PUvPP+KL>=d*4D=55(l%UPe4>wb%AD7H@+ ze74*b7jd?ofLEOiYL=uoza4Q5S#C?x!R@_Agio2g==es})QOG0%_q6YdM1osEznmy zkAVpaJB%b3LU`JhQ5Ji4HOcjH!S0LyDOP@2sGOL5;|&EAQZbWWH7UP{AO8Kdd~MF5 z-58Qz94ui>#bpY>W+cbT$#_qYSmWhh8}lebUZ1=cC6hX4E^m5PT6cNqZcO^d{aaaG z)`Fv0A%S=x%PF>{*s=QXm3D+g%~K;H`MqD$_8F%_`HUerBc;K${esPRTM~}st@R0O zil})^MN;LX8%`HjOsnedef#O)cSQ7;4=zo5a{Kw3wd9`N&L$cjXW+B@yEq<8c@%#7 z;#-X5WUxN5iLhAi5@M0Ft>b_PnMNKCYRq-vq$Jw;+QcZ*>&X4Bg{FHq#&w$wwPRCe zvlDA!CS`;yT?#^9In&Q~C6b`Qw_i{d7kKr0lx}s;hDLib1W9eivtxlfe6fUE9}{7J zEHfv=F5k){MEF(NK8|h5@{`s0r6HdCP(NGvLw7|daZ!SBBbkyzJ)WBeecczqT*at= z#)Gkm&-W|!^7{3t2h}?b*-XP>KjDi!%v+r&vuaz)8b?~zTg!x%4mK4Bl$lT&e1*L< zJs_xE%oqJOx|wz;g>kcvjlDfuslk7)ot!!xmDV%o@>L&=@tnA~`%3+IoIE;spLTCK z#kNvF?3Ey#Q(Gd@j=cUY;UV-u^_c4q%DtLC*shGyZ~5RY4D+hqnC?XZuky(zlaNJ#xO# zMM`^OX!1MDeSTFzS@CRz{@11Wnpnb?qdU4}YD)DY840f8A#s^42^~UReP&ZH2Cm@25+FJ@X}fmt-&c^lS3H6=O9uv_2p6J)8P_utPcD zc_2Qo?CIFkLq%6U>kNjSOjs5y%taLhIjM2ztlUnHZOZE|mrAzJJND0+i1H?wf|f8C z(q1$VtwAmVSBQWEa5!KJN{g+-CGALBlm-Aa3I=Y2(BL{Tga=X#1Glw-=;vViDxq6rO82N|Y#A|3L_TM%gh zcr!ZP-_p{A4q2EpKrW#9@47@IAHfA=VIsREoC^T3CdvslS*~YZRik;>tW9)NFeRWD zZ5G?oq+8E>5`{>n)K^os=;v6MSj^u!YTI!WJvEgb?vMH*tNt0+ORqj>l8gT}Qx>6K z?=n>rb)}$faGmXuvBTL_O<$H*v$}m6@drIe7Bf4gZY}`_vU^NlZvJrN)kI6QfHddt zEF9wFc8qn8$9OZ{?yjg0ir?SjI;t>qPg?@17rISJzm;_@GD3b|>L&lR2h`b{)BQ)v zF?Q=B-oyL&*s@C(m~r;`4<A!tpdr@WH*gYEK*8vxao#f## z5ZB05Wu$e;1#($In=W+K%^7u0pLy3iQC)FW!a`8`h+iqJE3@7-(wDONgjS2=o870r zXTC|&iPrM%L#p5(ExQsIG}56w1J+{E8^l({gtAPC}c@o>2nC6?x8 z7&Re0}Q-l_7ndNDGE|)(%yrIK;fnd_p!vZ#{eg2D7fVKF8%Bu0q^DY9{WsO=l0;N=H@>u9x#+2SoFGlZ|Aa0 zK6?vdcFz>6WDzJ@ouMP*By(r-geUJJE5phSyl$*%>EArL@12#h`F@`s>y}III$2WidyKPE~jyR^;ulHK#a^ ztL}W5RJ!S6_>(og`?QQpE;p+6Ni%=D^rd9UK0_4;7ZZsc<;%S$?uun%W@KPooL~@V zAPbBuSw0pq7Ln=C--LUzboZpCKMvnn#$UGJL-GUzd62X+i-dt#19k=cAO*sVjQ?3! z4VZzH0XIm1pM?dOlH8Ev0GND$alpvX!K^$j>)5Xomoy5uv8S*9Rc$W!wJVE7X>}WK zN?r7AwX=?MlIJ{OtPj0yxqrX9Z>!XSd&=qmpFP`f{$pULh5F*fyN??u__{d%Gq-do z?|AUJ+}t7PR8)4efThHil?(5+>^gV$?;h8H^JjJ>o?a*UE_;2O($c6HRh?6v9*eZq zrZ;)ETu7Pdt@nFd)=k|7K^c?#exDB)Pn%k1AKVf#q*7BzWEeuN$Cv)K#G`FLZW z9w;!GXvI9wU|v{n_PO&3ZAO~MelBQC7WMjcrJ>|i(AwwYjJ53EF;d-L1e^Fz>N3~ zm=Ui*G9n`*atLzMBm+Roh)g%h?STa*HXE8EN{uzc@=rehDyQ^Et~)bLUB4Ej%oS2+iR01sa&GbMFwA2hP4+N)5 zy?wJq&-QQi-vxhbGB}*FOHQuoBFFxT2%V_8a6F(l{dV%bRi5XvbJ@Gr&9gi@@%{Q%w%>sTmyUef!mhUQ z*5fr>E#@Vj-|y!>TQ)GuCx7RH9m`g1xb-CAv1V(`THRF5gzBea3*>8#CB6OU!P00y z-}>?F8{HMsQQaTi;w(S!f7F+eboR|J@fi)#U9p{sdY^V@RL^-+_w-=?MrNMIf3EpP zjD}oyRGTLVPFuX|N!QH?g)gm&FRK|Y3EtoHtY>%J4?~Frhq-C<*JsV_cIuk{Is3?$ heM=ctc6?F$V7{_aql2ICs*3*lb6tsk|Bq?S0{}5o;p_ka literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/ssl/consumer-core.cert b/idscp2/src/test/resources/ssl/consumer-core.cert new file mode 100644 index 000000000..894a5c1c0 --- /dev/null +++ b/idscp2/src/test/resources/ssl/consumer-core.cert @@ -0,0 +1,96 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 53 (0x35) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=DE, O=Fraunhofer, CN=IDS Test SubCA 2018 + Validity + Not Before: Dec 10 14:59:11 2019 GMT + Not After : Dec 9 14:59:11 2021 GMT + Subject: C=DE, O=Fraunhofer, OU=AISEC, CN=181ee43a-e0f5-4e1b-84ac-6eeb993e187f + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bf:3c:7c:1f:0f:82:56:9c:b1:bd:37:73:f3:43: + 7a:bf:6c:3c:63:d2:0b:36:7d:c4:bf:27:bb:88:cc: + 77:03:89:3c:bb:b3:3c:3e:29:98:42:a6:38:f5:b6: + 70:44:ca:b0:0b:ed:ed:96:74:62:05:fd:0f:20:f1: + 2a:d2:65:b3:91:33:9a:2d:af:8f:0f:03:20:bb:51: + ed:b5:77:9f:9e:c7:db:09:44:6b:e2:6a:96:b1:bf: + f2:fc:ff:95:ce:5c:bd:2d:60:56:e0:f7:8f:cb:0c: + b0:fb:01:5f:96:d1:35:d5:24:e8:ab:d8:ea:c4:7a: + ac:3a:f4:62:4e:e3:de:a4:2a:48:e2:ce:e4:7b:58: + 68:53:b7:fe:20:db:07:be:3e:52:e1:16:de:b9:25: + 08:04:28:71:40:19:29:c6:6e:a3:76:75:14:5a:8b: + 1e:62:8c:c0:59:f3:b0:ee:d7:6b:a9:13:45:09:75: + e7:02:d6:a4:18:a8:99:93:68:7e:46:9d:c0:ea:6d: + bb:e4:83:da:7f:0d:61:e1:03:8f:58:48:80:2b:64: + 7e:81:2a:a0:d0:3d:c5:c9:6c:73:62:77:53:21:e8: + 19:10:cb:ef:eb:6c:c6:54:4d:6e:30:37:0e:80:d9: + 4f:85:da:72:ce:15:2e:00:76:4b:a5:cf:72:96:07: + ff:0b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 14:7F:AA:8D:65:9B:0B:25:6F:BC:A6:F5:FC:BC:3B:6D:3E:D5:A1:E3 + X509v3 Authority Key Identifier: + keyid:CB:8C:C7:B6:85:79:A8:23:A6:CB:15:AB:17:50:2F:E6:65:43:5D:E8 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.aisec.fraunhofer.de/ids.crl + + Authority Information Access: + CA Issuers - URI:http://downloads.aisec.fraunhofer.de/rootcacert2016.cert + + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:consumer-core + Signature Algorithm: sha256WithRSAEncryption + 7d:aa:05:25:57:b8:fd:bb:54:88:06:1a:2a:ac:76:32:cd:6e: + 9f:93:21:3a:29:4b:07:02:28:b5:55:85:22:6c:7b:d7:b4:93: + 41:a1:ae:9c:e2:b9:61:66:af:da:51:08:4a:3b:df:73:30:2a: + bd:68:1d:66:8c:ca:10:64:82:6e:69:1e:93:cd:ba:f4:2f:cb: + ee:87:e6:d2:ea:b3:ad:a2:08:38:ac:a7:c3:a4:ae:e3:ba:a8: + 42:1e:e0:d6:8a:24:7c:23:c4:49:dc:4d:81:fa:8f:dc:86:26: + 7a:23:5d:d6:04:1c:2d:c3:fc:52:34:f6:21:8d:31:9c:2b:6e: + f7:a1:dc:03:3f:17:f6:6c:1c:ca:0e:7c:d0:21:0c:91:8c:56: + 0a:f4:2e:c2:68:90:f3:fe:f9:be:13:bd:49:07:95:e8:88:cc: + f2:36:2d:fb:27:2b:47:17:3b:ae:b8:2c:3d:d6:86:0e:da:df: + 3f:37:7a:ef:13:bf:06:9a:98:53:98:19:5a:1c:06:88:a2:45: + 8e:77:8a:ee:29:a8:fe:da:83:87:7a:0c:77:5e:c9:7b:42:19: + cb:8e:36:c7:4a:56:f3:28:4a:3a:a2:cf:ba:79:3b:a4:3b:a6: + ac:3b:c3:ee:8d:44:bb:08:24:c1:9a:20:65:46:96:47:37:55: + 9d:01:25:71 +-----BEGIN CERTIFICATE----- +MIIEQjCCAyqgAwIBAgIBNTANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJERTET +MBEGA1UECgwKRnJhdW5ob2ZlcjEcMBoGA1UEAwwTSURTIFRlc3QgU3ViQ0EgMjAx +ODAeFw0xOTEyMTAxNDU5MTFaFw0yMTEyMDkxNDU5MTFaMGExCzAJBgNVBAYTAkRF +MRMwEQYDVQQKDApGcmF1bmhvZmVyMQ4wDAYDVQQLDAVBSVNFQzEtMCsGA1UEAwwk +MTgxZWU0M2EtZTBmNS00ZTFiLTg0YWMtNmVlYjk5M2UxODdmMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvzx8Hw+CVpyxvTdz80N6v2w8Y9ILNn3Evye7 +iMx3A4k8u7M8PimYQqY49bZwRMqwC+3tlnRiBf0PIPEq0mWzkTOaLa+PDwMgu1Ht +tXefnsfbCURr4mqWsb/y/P+Vzly9LWBW4PePywyw+wFfltE11SToq9jqxHqsOvRi +TuPepCpI4s7ke1hoU7f+INsHvj5S4RbeuSUIBChxQBkpxm6jdnUUWoseYozAWfOw +7tdrqRNFCXXnAtakGKiZk2h+Rp3A6m275IPafw1h4QOPWEiAK2R+gSqg0D3FyWxz +YndTIegZEMvv62zGVE1uMDcOgNlPhdpyzhUuAHZLpc9ylgf/CwIDAQABo4IBJDCC +ASAwHQYDVR0OBBYEFBR/qo1lmwslb7ym9fy8O20+1aHjMB8GA1UdIwQYMBaAFMuM +x7aFeagjpssVqxdQL+ZlQ13oMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMDcGA1Ud +HwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuYWlzZWMuZnJhdW5ob2Zlci5kZS9pZHMu +Y3JsMFQGCCsGAQUFBwEBBEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL2Rvd25sb2Fk +cy5haXNlYy5mcmF1bmhvZmVyLmRlL3Jvb3RjYWNlcnQyMDE2LmNlcnQwHQYDVR0l +BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBgGA1UdEQQRMA+CDWNvbnN1bWVyLWNv +cmUwDQYJKoZIhvcNAQELBQADggEBAH2qBSVXuP27VIgGGiqsdjLNbp+TITopSwcC +KLVVhSJse9e0k0GhrpziuWFmr9pRCEo733MwKr1oHWaMyhBkgm5pHpPNuvQvy+6H +5tLqs62iCDisp8OkruO6qEIe4NaKJHwjxEncTYH6j9yGJnojXdYEHC3D/FI09iGN +MZwrbveh3AM/F/ZsHMoOfNAhDJGMVgr0LsJokPP++b4TvUkHleiIzPI2LfsnK0cX +O664LD3Whg7a3z83eu8TvwaamFOYGVocBoiiRY53iu4pqP7ag4d6DHdeyXtCGcuO +NsdKVvMoSjqiz7p5O6Q7pqw7w+6NRLsIJMGaIGVGlkc3VZ0BJXE= +-----END CERTIFICATE----- diff --git a/idscp2/src/test/resources/ssl/consumer-core.p12 b/idscp2/src/test/resources/ssl/consumer-core.p12 new file mode 100644 index 0000000000000000000000000000000000000000..6607767d644aea4ea7a11e98ac540c623b80283e GIT binary patch literal 2693 zcmY+^c{me}9|v%oZEjNTkejgC%rV#ZtNNm(CKKhpG734SAy+F$TXQXP--^vdu`x%k zkXx=UBv;PlOvtbA^Zb6l@9+1==lML(`~5ucKVNVH_dOth9ZujjgK(+Fo{!z-18@NH z3EU_Ufm`c$42Kgy3;$G*d;;j*?`Q-FVEg_0{%HVkNeK797kB{>I6sK9JVi88`A7=| z1ah)P6F~VZywpW&3z4n6S^2p{Kk$V%E=f<@tZGQd-P=J8Hk|AIlG1>yU0>xCvxy@* z72iX0B z^iNOOYZnWAA17!za&dVjSl|0p{BTpRI7}087_@ATLFmf_szlX=%EBu2{)pmvw&aJx zG6#b{-am5m!=QAl{S4&x>Mb)z5*-oub}-w+acmngdOgJ$qpu{_qK;afIiH=4fT0dv zNAG?Q*OEFm!#bpEeQa>jv&y9hxDw;TSjy=FZ{}(a5pzSxiIT=yj%fvu#`m%BZ09m_ zABR8-G2y_w6^$79uhophGzE4&(>1$(|D;UF)i$ z{*NqRf9&PtUYvuAHQHGCyKM@yxV~SE){sbW40>n@)%*)61=3!ny(OLjxUa>2!IoK0 znXUnu=C1Qy;hskX3utTp)SU~Hrj+#54C_ddr(fD0x3AlknVEjGmqTmVekc@oLI`68 zK1+t0bcN@aEZyisINyA$LE`vT(z>Z0fq3?+E`@;tcaa@5Rr3 zDaeeIVB_@uC`Nkfa0*$0Zj5upWWjWzgmqC8h@gfy&tULFrOE9jMxCrxyD07OQ(2>W^QkYMmZrbM((0 zctCIT{255Lfk%t;1j+&v>#Kt{&uPcSpZCIJIVUufon9=&wyH~_R9W&N$kGg+z@{PL zY(*5K;}aUBm)tJPzh0H|s}Dy~vKQ_UI>E+cr0q;n63IIU+Yk#YA`&h8BlimIKJQO* z!>${8(V*eS_X{sYHoMBdpCcd3E=#aCNmC*5fQBOZ%(*3Xfll1AzPbR~TGUrc)nT zGo*-VxZR358&I5M)MfLluG;rccK;s@j#tzcy*M-`Sa%a5lIh!Fs9wlw)bop)-bx++A>y3?OEjjAaxCa)^L!NG(rEE1#5k&`I5 z6jxwSFKq4RaIU#3b1T1)r~KLj=Wg7+<(_fk?xjKb9y*tnDN$rT0-YT{d+*5Pby|}J zrD^GNQbwHq_T$;Beg66qdG8 zO;2vL4nn~8uo;P`G2h1$nbFagdwVHS@XIKp8kbHi?kGryS*cQ0Ng6Y>;Lri{{K%n6 z!2k3N3*RC44)xH9!K&C-ZLMJM>Arm@q*@f9*Dt7R$B1gavI(*799D7w9`PA@B8)Q? zWfkS~_9YLpKjw{9e`Rimmr#@zNP_Y!!}`4kvuGV+-lc$c^-qN4{i)d>Fg}m+LD<97 zg$ELBiTJa(Vp*$6OEGE)e69OoBHnUlbIgoYX)7dTv-Y-h?qule3mJ(NX}H>gXT?0gKHAc5m4GP9-ld#v3ha=8)GL&M@z( ztjZ7TM${6Iw0NtV0S=eDj|RGCg`L>dgF~<4NvDjjK}SQv$kJ2h3Dyz*i9T!{lb-R!&|MzClh?;^W+@-tW{05F?w<5 z(z}Ip4kPmN2kYC|Z^v}BRDL0=UhcO^dNFA^chxakzg}Gh@wjfTfWL5H_6)4MskT6| zLM`|XL*e`eByU^Vuv%KU{vz7{J;8Sp76@$k;+mo}~m6Um+61^@$*YdK72rK z<3^vjq&E$`h^9B*&bu#RLLd2}EC>g~>`X%F+s?MRGpX;DG~T^dInUj$FsV07dbPG= zCVK7(#`e^P#jKik9~GUCP=w3>S4S>kga}CJeMEJi#7poF&yM-m$u)bS(k-btI07yU x=YoLM_}PIHU^bADxShH5uH&M#qzmn5a<0*Q!>&8%Qya3@?X+^2G#%o literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/ssl/provider-core-keystore.jks b/idscp2/src/test/resources/ssl/provider-core-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..21856439f263efd6f9e9499dd037f467166fe84b GIT binary patch literal 2443 zcma)7X*Anu7td;mt$FP<30k`({}8pb+FBAzOO2(LDv}6-3PBYus+L$v4=S}(sI8i6 z(U&PhEyFaOVAPaaDs2%pmg%C^nGWs5Y-c{aAKnl5ocp`?dG3AgJ-_GP&l{gNKp+rA zEZ{!`Ob~0)Z`@gVAP^i1WWc@v@)8JR2`~(71VMtqa1bm5wkF6WIBM$rRNd1Ykzk5- ziQb-#IsRnxpx~{+QuqatUGIQKO4*IO=>B!uR&Em0kn+vFP6bl+=APaFO~|W#MNYw7MtEKZfxRckrNs4i=g3+l znjfoiy33=byVU)WBI0PY_huUPH+?qJFL?WiciY>+4rRpFIcH|XB1$iVlPW8j9d#!1 zG_AYPId@Hx+u(Bl;cP)NarT_?w|Mg#Nf)**ZuufNk?q%)x_>-lj0Md^zWP;4U#)*K z!B-TjIbwl4#NmDQ)NxK(r_@^GYt)Z#C)zI7@ud9h*V1=hya`eJMs)KX8u}_P^Vi9smkA zzB=00sVZ|MutL58{R~{`e)Vz}a=Xu7>d7%LPG9Y8Lrkgy$9gn*o^nvw+$`lU zYL3awb2W+Gdbe8Ke7Ru8*7cs zo6ice&%>=+uOLeQv*X#*Hdz#QRgfj6Jn}ukEzky8y_b7z@_@88yTw%d;xWQzFjwe0 zl{GYKraN(cMNjT+^`YCV$L=QHe}m@8%=kRP)fW3@PzLEU!OLkD7&dAgv3)vj#zUhY z?vitwJMraJrQJM4aOhzjelpBp=Ii{y>#4pXZ$Z^1*Bz2s1J&Bi&{vt? z6=^G>4;BZjWj^N{!h|X{b_D$p>uE;F^f_*ez;Hq7NS5lIxu9R}4l(Y9zQbHI9}jGN zV#z&q=Gx_*`a$Qhif6YXr_H(4AB{=0n(VXDb}@%@ z`OZPj{8OV?oph5SXaQxdKO)inTJ91$TXYs(@F~pL>!YUdHs)3ckz2ypf3H7G8;JlClR<**9Ny#@Dj)5~=4 zw?%DUC5IByD_?|sqyM=O#TnvE{|b(?k;~THvth_I$o_Fa>kj8|oy4ilPo&9!TW6nv z1w!o7K!0JQ;i?=s@Pf^WOCPQvbgW4dcN_b2Vy*bY%}J-)ZQ~a7UoN+Xc4WQiwmmrl zDoG3Xua8`jESKIeb+had^skc-eUdI8hu)c0lWfyI_z8BN!-+pB6jr@N(IPtCe#wH3)8$^ayvMeZ0p}_IZiy6rRN6JSZHc4Q5JnV}7Q(Q2&^U za9^A`UA>1Og@kauU);*-qIX<-lMWI0!gOkO8D6px!VEMTi55 zpa>v$0YVl*W>FHN!zsP?v6rU1bbKTtO%wA zfIu`iHzoS3%9#=frhwI75TN`Y8RP-k-3&6aa9d|jl05+n82_1Zzh!6$#ga;-V@=Hg z3YJJEnqesxL?SlCibAA?(CKD0-~f;T*76ay;l#;(L%Q`wNh))I!BRnvd0BxLVy(t9QxKeb7~M z**DDAS!u33h=gZ+NsXQ}1k7e2PW~z`Jp#31l&4%{up1*n0#^|FO z^3?G1eeH8pC;dkLf{vy1jYVL%JMpSYIltr@&%jUOPFSe494d{scCAY|JKeN?@~+Kj zq#u9(HCW-Q3qGQ0A$+ zfLjmOhiQ8)@C zj!wgc{zEEU2p!J|iNlF~fR}`ncwxigl3*~*2_ORwe`5fWZTVM>5N2X@6q6#p@xLOm zn9O(@g+^z^iz#^kx2ybFrY=kcQ2IL@6!MP-2Gn+6i-aKog$%hE7V|74gwDd!m@N9g znI!%pVkUt>^>2G@dsx=IQg*@Hmg7xrJhjTEQk#^gfeTf~V!v~_dU^V6(?;x1sI~KP zeU;cMo7q6y2nc?W=4ykCpE~y{GE8|wka($y1|l5wANGzf^xys+QI?rhKqeQIgze;iIX}!_r+Y10HXm*UUZsW7YXY=u(?wu>|1!lMUi#N@w#nTe5!iIZUy z<9ofMX*b#pc-c6$+C196^D;8BvN9Mr8FCwNvN4CUun9A{xEcx@2!c3VJX~%?iKTfN z`Dv*|hH?fnAVFpxQBRj(g`oWW5`~b|;t~aCM+GATLkj~rab80ULjz+&Lo-7o1EVN$ zUSlBF$PCJ*iXBaiO2|%UWMyD(V&rEqXkz4IYGPz$*d*Jk-1}`puVZ4unkx$a4bztR zNDFNL;Qz*i^HwPL6rqJ%W_cQ)%jFLbZ|Lw|Aei*@uz-!~p9wy@eVL9}$Z6XBS|8*; zxwv22g!iv_SNWVrH_wF$3NAUmOF#QZz%CTdlb3sNw@UWv=|wh^vvPl_e7G+xPJ}u*t%Z+M%(#+p3eJNS8&rrp|#YAF9`Esv`yJDG`85tNCCm6&T z$O7X^mXAe@MP&N(H{qTv-92gPkHdGC@s}<5kUYUa9we>IB4HrbfL#GUNP#dT<9`-b z17;v)zzq`MXJG-RBsb(Z045(`956C;Fe^{XI`-?tC5^&u?CI-&Rh!Fw?aE?NTHVH* zQWt$&?X2URqBo_?%%KO+bVV7o^tyCXU{gA{}|Y5p}u(W?&HP@zAn!H%q<<-&U{yUv~cyT>)){Fxnzr`Jio%U<86v@|M4Rp(Tv$0BXD z=}n$37g8pA>;2xAbyIgiP{!oG-{-@{)25c$2R8?+y7&c{MNM9kA7RJ(Z1w_kKHk`; z2MSCkS~1Tvm>1TYeeQfhn~~n3MZG>swdpjJ~nf5f<)-q z?s*~Vw_L8+O;{;nt?Z(}`1kMG1=CWVJ!OfTcKY<(o#33vT3nh0%ZL#Lh>Z9Nm=WIr zGvYN!Mr33}4nc03WIz*O1_Wk410zdt1~iE>a3CU+%NR%j;~ALAg+ZAdoWFxhlVDk# zQ1)A`(i7%?ORcNq;=x?|y*Z3WX)5^ZP<=KXH3I`Oftuj}Q zSDKNuYtNOkKPQU*EKl(;+iq$ck?AJ6J+Q#UWkTG<&^%2+&*71XQk5I z717^=!kT;oJLjpr7wI>M{t?k0-Tbg&(mrcsv z--vS+wd_zh`P-x;@krW&!vYZp*0yEK_j{k>a?f{ZIUG4@Rhp=xNTn*{a$B)^k&K5k zU#qxRwY+WYJ@V7ryR@5=D@3ro@wU*ufW6smQ-7u9Z?Sjv<6bYt9~dsB{eI7zm}`s7 zKTe&0%B$F5+uPTW?AQ3gpz$qI20Yz!d|PYf3gu;|MOTXl=s!z!j(tH{25d7h2jxb2 z76Su41Dyq03pCo)GD=Dctn~Ghi*oc5GmBG`_0r%)w_ZxBer8Is9#GC8gpEU+4Or&0 zGcvMx7`Pd@!1xACZ5B{7Qu535a`F>_IIyd6q{fzF*(U_B*iP(vfdl*wr@P zdc0<<#k|Dx`~BQ!%LZooN#)fo*vBK$jsCD&o$qO z(U9woYV!oaX^VF~>AD%A@TFDpWi`Vk!TWoj_3V!OVJMN{FgI=f`mCAVPF?dqXCL{p hZz-e7jxTC#=eqI=O`fm2IPt*Zf?a*x#Zzxh1OSMh<4XVl literal 0 HcmV?d00001 diff --git a/idscp2/src/test/resources/ssl/provider-core.cert b/idscp2/src/test/resources/ssl/provider-core.cert new file mode 100644 index 000000000..8f4f2bd5b --- /dev/null +++ b/idscp2/src/test/resources/ssl/provider-core.cert @@ -0,0 +1,96 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 52 (0x34) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=DE, O=Fraunhofer, CN=IDS Test SubCA 2018 + Validity + Not Before: Dec 10 14:55:24 2019 GMT + Not After : Dec 9 14:55:24 2021 GMT + Subject: C=DE, O=Fraunhofer, OU=AISEC, CN=8fda8b4e-250a-4b43-a744-d9a4cdee3c06 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:f0:a9:bc:ce:14:96:e5:fc:8e:ac:75:b1:6e:49: + ce:b3:9c:15:fa:ca:ef:6a:03:de:7f:2a:04:e6:6f: + 7b:4c:5f:83:77:f4:00:4d:88:ff:30:7a:14:ad:62: + 2d:c9:dd:71:1a:69:4d:39:aa:18:a4:4a:87:25:be: + b9:93:8d:58:67:41:49:20:fc:97:14:16:25:8c:03: + a5:09:9a:3f:56:23:a1:f4:4a:2a:69:d1:61:28:44: + 19:4e:0c:ab:07:68:1f:d9:42:11:15:45:66:f4:03: + 8b:54:a6:30:81:b5:84:52:df:ef:f5:b5:e9:6f:9c: + 45:6b:78:4d:e3:59:62:bb:f2:c1:3a:dc:8b:0a:df: + e6:68:72:08:8a:33:26:52:e6:0c:80:a9:62:de:46: + 5c:21:be:7b:4e:3d:63:dc:b3:5a:35:79:ed:cd:c9: + a0:46:d6:c5:e6:b8:21:78:62:48:27:a6:c8:e2:22: + 38:09:a2:e3:30:c5:ba:77:95:16:99:c8:93:98:ab: + 28:59:06:ae:67:66:09:0d:1d:7f:ab:eb:98:b9:de: + da:d8:a7:ec:56:af:3d:cd:6b:50:7a:33:4e:58:40: + f7:dc:bd:0f:4f:5a:41:46:2e:2e:ce:c1:b8:8a:40: + c2:a0:7b:85:60:26:1f:b2:c4:55:cf:72:58:54:22: + 66:17 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + B0:88:A0:81:1D:CF:C2:B2:A5:88:62:37:8B:50:3A:28:0B:19:59:69 + X509v3 Authority Key Identifier: + keyid:CB:8C:C7:B6:85:79:A8:23:A6:CB:15:AB:17:50:2F:E6:65:43:5D:E8 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.aisec.fraunhofer.de/ids.crl + + Authority Information Access: + CA Issuers - URI:http://downloads.aisec.fraunhofer.de/rootcacert2016.cert + + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:provider-core + Signature Algorithm: sha256WithRSAEncryption + a4:f1:bc:41:bc:72:3a:ab:94:88:8c:f1:ad:4c:a7:b1:ab:18: + 9b:a7:94:3d:7b:d7:5e:e2:9c:4b:71:c6:4a:95:8d:d8:76:a7: + ed:71:e9:1d:eb:7c:73:bf:9b:2d:9c:3d:da:5e:41:6a:02:2f: + e3:63:4d:3d:11:74:d6:78:e7:6b:67:15:d2:cb:77:83:a7:45: + 48:18:19:85:a2:52:72:43:5a:29:02:93:8b:e1:f6:2e:c1:ae: + 0b:0e:50:54:96:83:47:60:c7:ac:43:42:29:a9:5a:9f:bf:7e: + ba:5f:b8:74:87:85:19:43:30:27:f4:b6:e2:72:30:5f:0b:50: + db:47:28:5c:73:84:7d:24:2c:42:76:5f:cc:65:d6:cd:d2:8a: + 3e:f5:6f:02:d7:1e:17:6c:b7:db:34:4f:56:22:ab:50:e3:89: + e5:cb:1f:1a:04:7a:e3:48:da:ec:e5:de:a3:f5:88:9f:d6:93: + 88:aa:2f:29:e3:e5:35:75:5f:b9:35:5e:1b:15:5f:70:69:bc: + 7e:89:04:de:ef:a9:b4:8b:86:d2:8f:0c:37:63:eb:e8:44:e8: + b5:e4:bd:e4:a4:5a:07:25:fd:39:ef:19:fc:b6:3d:05:f3:bf: + 4c:a8:86:a7:54:e8:b6:45:3d:e8:e0:29:63:9f:28:6d:f6:f3: + fc:03:0c:70 +-----BEGIN CERTIFICATE----- +MIIEQjCCAyqgAwIBAgIBNDANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJERTET +MBEGA1UECgwKRnJhdW5ob2ZlcjEcMBoGA1UEAwwTSURTIFRlc3QgU3ViQ0EgMjAx +ODAeFw0xOTEyMTAxNDU1MjRaFw0yMTEyMDkxNDU1MjRaMGExCzAJBgNVBAYTAkRF +MRMwEQYDVQQKDApGcmF1bmhvZmVyMQ4wDAYDVQQLDAVBSVNFQzEtMCsGA1UEAwwk +OGZkYThiNGUtMjUwYS00YjQzLWE3NDQtZDlhNGNkZWUzYzA2MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8Km8zhSW5fyOrHWxbknOs5wV+srvagPefyoE +5m97TF+Dd/QATYj/MHoUrWItyd1xGmlNOaoYpEqHJb65k41YZ0FJIPyXFBYljAOl +CZo/ViOh9EoqadFhKEQZTgyrB2gf2UIRFUVm9AOLVKYwgbWEUt/v9bXpb5xFa3hN +41liu/LBOtyLCt/maHIIijMmUuYMgKli3kZcIb57Tj1j3LNaNXntzcmgRtbF5rgh +eGJIJ6bI4iI4CaLjMMW6d5UWmciTmKsoWQauZ2YJDR1/q+uYud7a2KfsVq89zWtQ +ejNOWED33L0PT1pBRi4uzsG4ikDCoHuFYCYfssRVz3JYVCJmFwIDAQABo4IBJDCC +ASAwHQYDVR0OBBYEFLCIoIEdz8KypYhiN4tQOigLGVlpMB8GA1UdIwQYMBaAFMuM +x7aFeagjpssVqxdQL+ZlQ13oMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMDcGA1Ud +HwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuYWlzZWMuZnJhdW5ob2Zlci5kZS9pZHMu +Y3JsMFQGCCsGAQUFBwEBBEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL2Rvd25sb2Fk +cy5haXNlYy5mcmF1bmhvZmVyLmRlL3Jvb3RjYWNlcnQyMDE2LmNlcnQwHQYDVR0l +BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBgGA1UdEQQRMA+CDXByb3ZpZGVyLWNv +cmUwDQYJKoZIhvcNAQELBQADggEBAKTxvEG8cjqrlIiM8a1Mp7GrGJunlD17117i +nEtxxkqVjdh2p+1x6R3rfHO/my2cPdpeQWoCL+NjTT0RdNZ452tnFdLLd4OnRUgY +GYWiUnJDWikCk4vh9i7BrgsOUFSWg0dgx6xDQimpWp+/frpfuHSHhRlDMCf0tuJy +MF8LUNtHKFxzhH0kLEJ2X8xl1s3Sij71bwLXHhdst9s0T1Yiq1DjieXLHxoEeuNI +2uzl3qP1iJ/Wk4iqLynj5TV1X7k1XhsVX3BpvH6JBN7vqbSLhtKPDDdj6+hE6LXk +veSkWgcl/TnvGfy2PQXzv0yohqdU6LZFPejgKWOfKG328/wDDHA= +-----END CERTIFICATE----- diff --git a/idscp2/src/test/resources/ssl/provider-core.p12 b/idscp2/src/test/resources/ssl/provider-core.p12 new file mode 100644 index 0000000000000000000000000000000000000000..830797f6993b334c9886c6aae7031b06a96bcb4d GIT binary patch literal 2693 zcmV;03VQW0f(n5G0Ru3C3P%PBDuzgg_YDCD0ic2kI0S+UG%$h+Fff7y=LQKXhDe6@ z4FLxRpn?S0FoFcs0s#Opf&|S52`Yw2hW8Bt2LUh~1_~;MNQUC=P4`0diku|3S-viqdC5RvVs(UOdNUl56m%D<=xme)b z(Lj`prw;QCn^QG)H!EQa>LfG5&oVGnDs>tfBcWZd-R(=P+%N^V#o#daU^6#NN1ZHO zd6fw@D&3T~1o5)A!QA0DcoJ^mPa>I11jI9?7#8xD0u?uotnIAw0y4xS?ZQdfu0+>& z;V5@m@Rgv4GCaPVqDD)Uz;|k@{HEdy7b-Ij6IS#c5+#+3gxAB*#T7GE87ioc>Lqt) zJoG-$y!;$|KQ)BNKz&XsI>$0XVMe0A26znjv@ym(9nbKeTnUS=283=deM)@-h`TO> zsc(s?w8aXfjRaoOo{aY*Q&S+ZhK_QE)I&c@uHLTwiHmB=3So(?W|8)A#`l77{~Qjg z`_Ta_lpnr}#0)dDN%Tr*WDb@c4#w!=12LJ906C|_nFyU|C1cDscx7ZI*uy)~qTtAF zSGSN=Jlzv~qBQd|8qJPr+V17BLKCB7-)HQJpN_NOQgAz*m;d(2fs_#rOaia zS=GZKXH$Fs5YUi1tjIhJsv((G@qQRSNImd$K%&}BbiA3mY};mB?nJL8J`N5iq%1N9 zv)QPr8@UWg?^2#DE0^lB7te=4t%`s}a}z<59{um^f$gabq&O@GC1U03qP!Q;bh|$D zydu^7oo>sL25~rGnWl=$)L(K2o>3B$)&}Mm%0@9$YIn7iZt_?MN2IFAB&66jyZna_N`}IO0|j8=uIaGn)_Cr@UTJ5Tvs|X4NfH2=B+gxn^lavqNCSqvnynm4MoJS45G&@y!~wosRZ(L z(-okxDS-KLrMabk)klbB98!w1Hwcj+YAhOOIWd{9F3UrD7=vR))WS@Q{gNin9<6E~ zY2uq(GWfY0_Zqy*{2c5L8*bGfk9S?+G76kK8LXoWC_O`d|fhmm9 z-i0MoDOJShVV(KE4Mf}cPFF9f4B;PCkLOPY6CsW&LrYYU#RUMZImHx}>&N+M;#}<% zh#=Z3AA)4xP{hcoBk3M9aDF#`Iwt#rie-1JlCB|%$f5V-lNsw%+_pZ)Rz3e5X6uR3 zYR8YJs40ylQ<$28U3TJ3_e)bvXvF}urqm-!^@L1-uO|k)7LcmyDvdq(i6OkE?(e5G z{A+njhF>&SMnJRC01AFo29F3z^lR0`cLgtZ0#X`C-E6JP?5sRF5RkG;%4Dyy?@pQf zFoFd^1_>&LNQUp$?v0_$$Vh(@(gh%^dOXv5Exv4LOzZEQ z$6nkDS$@L&5#ga-1@-n!IEgNgXi$MCq*T1FIR>+4UrE_iQ+vBTa|i`dh*UGUf}~b) z+S$2a%k)07^pPXPghmATr+0d=4wFZU(@NfpL(tj53Ry7*^0xk2_bMyo^TuetHP)Li z%o$a1ch@Rsv1|@de>@ZEyH*l-CBN)|n9OUFk*Qd%MLGQh3untshR5- zG~Hfmr5t_L_?$_M^x`H$noAaze^A-Ivmz@%(X98RR50mbYrIW_rRA)J1Ad8F?g9=v zsf)k3#@bytCBrDkI~pd&j|X*)yrXqeQ=`Aym1 z;)=pCX2b+?-@ ztZy|hKFyb1vrv$%FjPNAR$>It#DUEbQz0p!vUB`=nh1p#oJ(O6+~Dy_UDL({job8= zYbUQS$|ZU5kpU}NoBsd9q6ajj+>(Ib<&E-Xjc+xl=7ng@x?PPJY<^|6V_%J? zhJoyaO9FsPkzPK^KjJ`vGg=gs1w_N%qt^si`-pX5XtyvJWsanz%TfHOH)$nW(2{4h zj{sJOISE!j8QiDembWVq4Y{<%g+(!e!DrCIE+AdU(H2uwTgv*zQ~aP2H_;}>h&d}_ ztRYHVLo?=g(Uxh46%4h%g0Tbs#Ac`vo*5VY$B;bMXYuS&9$boLcn+EUt#Xb&K*!ur zRs&HrtJ20j5mXCv!eD(nIyLENrD1@|XF6jV9l&eCJV-jVJkeKD-5)V{F{D@r=T!eZ*5`;G6J19mmKanB^r;Y=cVR zFLH3isFZcvw3VhE(y?CE9-znszOAs5iq>U&VtA#XQD!rT01QUYfySIA?jmRM=_Bv` z3O?zFPy#mXoJ?bXeCW%!1CW)Ip9o7(u;tvB7X_W%Ct-xR7m%d0x}BT Date: Thu, 9 Jan 2020 16:10:29 +0100 Subject: [PATCH 031/237] improve comments, Logging, error handling --- .../aisec/ids/idscp2/IDSCPv2Initiator.java | 8 +- .../secure_channel/NativeTLSDriver.java | 38 ++++++- .../client/InputListenerThread.java | 3 + .../secure_channel/client/TLSClient.java | 96 ++++++++--------- .../CustomX509ExtendedKeyManager.java | 6 +- .../keystores/TLSPreConfiguration.java | 4 + .../secure_channel/server/TLSServer.java | 100 +++++++++--------- .../server/TLSServerThread.java | 6 +- .../interfaces/SecureChannelDriver.java | 15 +++ .../drivers/interfaces/SecureServer.java | 4 +- .../ids/idscp2/error/IDSCPv2Exception.java | 2 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 17 +-- .../configuration/IDSCPv2Callback.java | 13 +++ .../configuration/IDSCPv2Configuration.java | 49 +++++++-- .../configuration/IDSCPv2Settings.java | 2 +- .../secure_channel/SecureChannel.java | 19 ++-- .../secure_channel/SecureChannelEndpoint.java | 15 ++- 17 files changed, 255 insertions(+), 142 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java index d0a7c5f96..23994ca47 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java @@ -3,13 +3,15 @@ import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; /** - * An interface for the IDSCPv2Initiator class, that implements a callback function notify the user, a new connection - * was created + * An interface for the IDSCPv2Initiator class, that implements callback functions that notifies the user about + * new connections, errors and closed connections * * Developer API * * Methods: - * void onConnect(IDSCPv2Connection) to notify the user, a new connection was created + * void onConnect(IDSCPv2Connection) to notify the user a new connection was created + * void errorHandler(String error) to notify the user about an error occurred + * void connectionClosedHandler(String connectionId) to notify the user about connection was closed * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 471d7672c..9303d6cc0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -6,20 +6,48 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +/** + * An implementation of SecureChannelDriver interface on TLSv1.3 + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class NativeTLSDriver implements SecureChannelDriver { + private static final Logger LOG = LoggerFactory.getLogger(NativeTLSDriver.class); @Override public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { - TLSClient tlsClient = new TLSClient(settings, callback); - tlsClient.connect(settings.getHost(), settings.getServerPort()); + try { + TLSClient tlsClient = new TLSClient(settings, callback); + tlsClient.connect(settings.getHost(), settings.getServerPort()); + + } catch (IOException | NoSuchAlgorithmException | KeyManagementException e){ + + LOG.error("listen() failed. {}", e.getMessage()); + LOG.debug(Arrays.toString(e.getStackTrace())); + callback.secureChannelConnectHandler(null); + } } @Override public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback) { - TLSServer tlsServer = new TLSServer(settings, callback); - tlsServer.start(); - return tlsServer; + try { + TLSServer tlsServer = new TLSServer(settings, callback); + tlsServer.start(); + return tlsServer; + + } catch (IOException | NoSuchAlgorithmException | KeyManagementException e){ + LOG.error("listen() failed. {}", e.getMessage()); + LOG.debug(Arrays.toString(e.getStackTrace())); + } + + return null; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 83a808c7d..98b908932 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -1,6 +1,8 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; @@ -18,6 +20,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class InputListenerThread extends Thread implements InputListener { + private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); private InputStream in; private ArrayList listeners = new ArrayList<>(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 3bd6bd8a7..3d16fe160 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -59,55 +59,51 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private IDSCPv2Callback callback; private String connectionId = null; - public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback){ + public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) + throws IOException, KeyManagementException, NoSuchAlgorithmException{ this.callback = callback; /* init TLS Client */ - try { - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( - clientSettings.getTrustStorePath(), - clientSettings.getTrustStorePassword() - ); - - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( - clientSettings.getKeyStorePath(), - clientSettings.getKeyStorePassword(), - clientSettings.getCertAlias(), - clientSettings.getKeyStoreKeyType() - ); - - SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); - sslContext.init(myKeyManager, myTrustManager, null); - - SSLSocketFactory socketFactory = sslContext.getSocketFactory(); - - //create server socket - clientSocket = socketFactory.createSocket(); - - SSLSocket sslSocket = (SSLSocket) clientSocket; - SSLParameters sslParameters = sslSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(false); //use server priority order - sslParameters.setNeedClientAuth(true); - sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 - sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher - sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification - sslSocket.setSSLParameters(sslParameters); - LOG.info("TLS Client was initialized successfully"); - - } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ - LOG.error("Init TLS Client failed"); - e.printStackTrace(); - } + + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + clientSettings.getTrustStorePath(), + clientSettings.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + clientSettings.getKeyStorePath(), + clientSettings.getKeyStorePassword(), + clientSettings.getCertAlias(), + clientSettings.getKeyStoreKeyType() + ); + + SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + + SSLSocketFactory socketFactory = sslContext.getSocketFactory(); + + //create server socket + clientSocket = socketFactory.createSocket(); + + SSLSocket sslSocket = (SSLSocket) clientSocket; + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(false); //use server priority order + sslParameters.setNeedClientAuth(true); + sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 + sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification + sslSocket.setSSLParameters(sslParameters); + LOG.debug("TLS Client was initialized successfully"); } public void connect(String hostname, int port){ SSLSocket sslSocket = (SSLSocket) clientSocket; if (sslSocket == null || sslSocket.isClosed()){ - System.out.println("Client socket is not available"); + LOG.warn("Client socket is not available"); callback.secureChannelConnectHandler(null); return; } @@ -115,7 +111,7 @@ public void connect(String hostname, int port){ try { sslSocket.connect(new InetSocketAddress(hostname, port)); - LOG.info("Client is connected to server {}:{}", hostname, port); + LOG.debug("Client is connected to server {}:{}", hostname, port); //set clientSocket timeout to allow safeStop() clientSocket.setSoTimeout(5000); @@ -128,10 +124,10 @@ public void connect(String hostname, int port){ //start tls handshake sslSocket.addHandshakeCompletedListener(this); - LOG.info("Start TLS Handshake"); + LOG.debug("Start TLS Handshake"); sslSocket.startHandshake(); } catch (SSLHandshakeException | SSLProtocolException e){ - LOG.error("TLS Handshake failed: {}", e.getMessage()); + LOG.warn("TLS Handshake failed: {}", e.getMessage()); disconnect(); callback.secureChannelConnectHandler(null); } catch (IOException e) { @@ -142,7 +138,7 @@ public void connect(String hostname, int port){ } private void disconnect(){ - LOG.info("Disconnecting from server"); + LOG.debug("Disconnecting from tls server"); //close listener if (inputListenerThread != null && inputListenerThread.isAlive()) { inputListenerThread.safeStop(); @@ -169,14 +165,14 @@ public void close() { public void send(byte[] data){ if (!isConnected()){ - LOG.error("Client cannot send data because socket is not connected"); + LOG.warn("Client cannot send data because socket is not connected"); } else { try { out.write(data); out.flush(); - LOG.info("Send message: {}", new String(data)); + LOG.debug("Send message: {}", new String(data)); } catch (IOException e){ - LOG.error("Client cannot send data"); + LOG.warn("Client cannot send data"); e.printStackTrace(); } } @@ -193,7 +189,7 @@ public SSLSession getSslSession() { @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { //start receiving listener after TLS Handshake was successful - LOG.info("TLS Handshake was successful. Starting input listener thread"); + LOG.debug("TLS Handshake was successful. Starting input listener thread"); SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; inputListenerThread.start(); @@ -206,7 +202,7 @@ public void onMessage(int len, byte[] rawData) { System.arraycopy(rawData, 0, data, 0, len); if ((new String(data, StandardCharsets.UTF_8)).equals(TlsConstants.END_OF_STREAM)){ //End of stream, connection is not available anymore - LOG.info("Client is terminating after server disconnected"); + LOG.debug("Client is terminating after server disconnected"); disconnect(); callback.connectionClosedHandler(this.connectionId); } else { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java index f838cf09e..c9c7e076b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java @@ -55,7 +55,7 @@ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket s if ((cachedAliases.containsKey(this.certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { - LOG.info("CertificateAlias is {}", this.certAlias); + LOG.debug("CertificateAlias is {}", this.certAlias); return this.certAlias; } else { LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); @@ -84,7 +84,7 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock if (keyType.equals(this.keyType)){ if ((cachedAliases.containsKey(certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { - LOG.info("CertificateAlias is {}", this.certAlias); + LOG.debug("CertificateAlias is {}", this.certAlias); return this.certAlias; } else { LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); @@ -103,7 +103,7 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock public X509Certificate[] getCertificateChain(String certAlias) { if (certAlias.equals(this.certAlias)){ X509Certificate[] ret = delegate.getCertificateChain(certAlias); - LOG.info("Certificate Chain: {}", Arrays.toString(ret)); + LOG.debug("Certificate Chain: {}", Arrays.toString(ret)); return ret; } else { LOG.warn("Invalid certAlias '{}' in getCertificateChain() in class X509ExtendedKeyManager", certAlias); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java index 3ce92fca5..9fa814782 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java @@ -1,5 +1,8 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javax.net.ssl.*; import java.io.IOException; import java.io.InputStream; @@ -17,6 +20,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class TLSPreConfiguration { + //private static final Logger LOG = LoggerFactory.getLogger(TLSPreConfiguration.class); public static TrustManager[] getX509ExtTrustManager( String trustStorePath, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 9bf576e23..fb863aa0d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -11,6 +11,7 @@ import javax.net.ssl.*; import java.io.IOException; import java.net.ServerSocket; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -36,61 +37,60 @@ public class TLSServer extends Thread implements SecureServer { private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); private volatile boolean isRunning = false; - private ServerSocket serverSocket = null; + private ServerSocket serverSocket; private IDSCPv2Callback callback; - public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback){ + public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback) + throws IOException, NoSuchAlgorithmException, KeyManagementException { this.callback = callback; /* init server for TCP/TLS communication */ - try { - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( - serverSettings.getTrustStorePath(), - serverSettings.getTrustStorePassword() - ); - - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( - serverSettings.getKeyStorePath(), - serverSettings.getKeyStorePassword(), - serverSettings.getCertAlias(), - serverSettings.getKeyStoreKeyType() - ); - - // create tls context based on keyManager and trustManager - SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); - sslContext.init(myKeyManager, myTrustManager, null); - SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); - - //create server socket - serverSocket = socketFactory.createServerSocket(serverSettings.getServerPort()); - //set timeout for serverSocket.accept() to allow safeStop() - serverSocket.setSoTimeout(5000); - - SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; - SSLParameters sslParameters = sslServerSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite - sslParameters.setNeedClientAuth(true); //client must authenticate - sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 - sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite - //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment - //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification - sslServerSocket.setSSLParameters(sslParameters); - LOG.info("Server was initialized successfully"); - - } catch (NoSuchAlgorithmException | KeyManagementException | IOException e){ - LOG.error("Init SSL server socket failed"); - e.printStackTrace(); - } + /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + * hostVerification and algorithm constraints */ + LOG.debug("Create trust manager for tls server"); + TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + serverSettings.getTrustStorePath(), + serverSettings.getTrustStorePassword() + ); + + /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + * connection specific key selection via key alias*/ + LOG.debug("Create key manager for tls server"); + KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + serverSettings.getKeyStorePath(), + serverSettings.getKeyStorePassword(), + serverSettings.getCertAlias(), + serverSettings.getKeyStoreKeyType() + ); + + LOG.debug("Set tls security attributes and create tls server socket"); + + // create tls context based on keyManager and trustManager + SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + sslContext.init(myKeyManager, myTrustManager, null); + SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); + + //create server socket + serverSocket = socketFactory.createServerSocket(serverSettings.getServerPort()); + //set timeout for serverSocket.accept() to allow safeStop() + serverSocket.setSoTimeout(5000); + + SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; + SSLParameters sslParameters = sslServerSocket.getSSLParameters(); + sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite + sslParameters.setNeedClientAuth(true); //client must authenticate + sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 + sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite + //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment + //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification + sslServerSocket.setSSLParameters(sslParameters); + LOG.debug("TLS server was initialized successfully"); } @Override public void run(){ - LOG.info("Starting server"); + LOG.debug("Starting tls server"); if (serverSocket == null || serverSocket.isClosed()){ LOG.error("TLS Server socket is not available"); @@ -99,7 +99,7 @@ public void run(){ SSLSocket sslSocket; isRunning = true; - LOG.info("Server is running"); + LOG.debug("TLS server is running"); while(isRunning){ try { sslSocket = (SSLSocket) serverSocket.accept(); @@ -110,14 +110,14 @@ public void run(){ //alternative: close serverSocket. But then we cannot reuse it continue; } catch (IOException e) { - System.out.println("TLS Server failed"); + LOG.error("TLS Server failed"); e.printStackTrace(); isRunning = false; return; } //start new server thread - LOG.info("New TLS client has connected. Create new server session"); + LOG.debug("New TLS client has connected. Create new server session"); TLSServerThread server = new TLSServerThread(sslSocket, this.callback); sslSocket.addHandshakeCompletedListener(server); server.start(); @@ -127,7 +127,7 @@ public void run(){ try { serverSocket.close(); } catch (IOException e) { - LOG.error("Could not close TLS server socket"); + LOG.warn("Could not close TLS server socket"); e.printStackTrace(); } } @@ -135,7 +135,7 @@ public void run(){ @Override public void safeStop(){ - LOG.info("Stopping server"); + LOG.debug("Stopping tls server"); isRunning = false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 0399dceb4..ffec566ae 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -104,7 +104,7 @@ public void run(){ } } callback.connectionClosedHandler(this.connectionId); - LOG.info("ServerThread is terminating"); + LOG.trace("ServerThread is terminating"); try { out.close(); in.close(); @@ -121,7 +121,7 @@ public void send(byte[] data) { try { out.write(data); out.flush(); - LOG.info("Send message: " + new String(data)); + LOG.trace("Send message: " + new String(data)); } catch (IOException e){ LOG.error("Server cannot send data"); e.printStackTrace(); @@ -155,7 +155,7 @@ public boolean isConnected() { @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { - LOG.info("TLS handshake was successful"); + LOG.debug("TLS handshake was successful"); SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 1d4535d23..2a1e7ea83 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -3,6 +3,21 @@ import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +/** + * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function for IDSCPv2 clients and + * a listen() function for IDSCPv2 servers + * + * Developer API + * + * Methods: + * void connect(IDSCPv2Settings, IDSCPv2Callback) to create an IDSCPv2 connection to the host from the settings + * registers a callback for errors and return of a secure channel + * + * SecureServer listen(IDSCPv2Settings, IDSCPv2Callback) to create an IDSCPv2 server configured by the IDSCPv2 settings + * registers a callback for errors and new incoming connections + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public interface SecureChannelDriver { void connect(IDSCPv2Settings settings, IDSCPv2Callback callback); SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java index 7e893a04a..86ab13a90 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java @@ -1,11 +1,13 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; /** - * + * An interface for the IDSCPv2 Secure Server * * Developer API * * Methods: + * void safeStop() to terminate the server + * boolean isRunning() to check if the server is running * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java index e16824f26..ad16f97f3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java @@ -5,7 +5,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IDSCPv2Exception extends RuntimeException{ +public class IDSCPv2Exception extends Exception{ public IDSCPv2Exception(String message) { super(message); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index 19cc9cad5..a1eb0f4cf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -3,15 +3,13 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpClose; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * The IDSCPv2 Connection class is the entry point for the IDSCPv2 protocol. It runs a peer (client or server) and - * establishes a secure state by building a secure transfer channel, verifies the dynamicAttributeToken and RAT + * The IDSCPv2 Connection class * - * Developer API: - * - * Constructors: - * IDSCPv2Connection(SecureChannel sc, String connectionID) + * User/Developer API: * * Methods: * void close() to close an IDSCP connection @@ -22,6 +20,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class IDSCPv2Connection implements IdscpMsgListener { + private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Connection.class); private SecureChannel secureChannel; private String connectionId; @@ -33,21 +32,25 @@ public IDSCPv2Connection(SecureChannel secureChannel, String connectionId){ } public void close() { + LOG.info("Close idscp connection"); + LOG.debug("Send IDSCP_CLOSE"); IdscpMessage msg = IdscpMessage.newBuilder() .setType(IdscpMessage.Type.IDSCP_CLOSE) .setIdscpClose(IdscpClose.newBuilder().build() ).build(); send(msg); + LOG.debug("Close secure channel"); secureChannel.close(); } public void send(IdscpMessage msg) { + LOG.debug("Send idscp message of type {}", msg.getType()); secureChannel.send(msg); } @Override public void onMessage(IdscpMessage msg) { - System.out.println("Received new IDSCP Message: " + msg.toString()); + LOG.info("Received new IDSCP Message: " + msg.toString()); } public boolean isConnected() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java index 8006525bb..af6921d6d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java @@ -2,6 +2,19 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +/** + * An callback interface, that implements callback functions that notifies about new secureChannels, errors and closed + * connections + * + * Developer API + * + * Methods: + * void secureChannelConnectHandler(SecureChannel) to notify the client about a new secure channel + * void secureChannelListenHandler(SecureChannel) to notify the server about a new secure channel + * void connectionClosedHandler(String connectionId) to notify listener about connection was closed + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public interface IDSCPv2Callback { void secureChannelConnectHandler(SecureChannel secureChannel); void secureChannelListenHandler(SecureChannel secureChannel); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index 4ee926427..77009d352 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -2,22 +2,30 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; +import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.UUID; /** - * IDSCPv2Configuration Class, provides IDSCPv2 API to the User (IDSCPv2Initiator) + * IDSCPv2Configuration class, provides IDSCPv2 API to the User (IDSCPv2Initiator) * - * Developer API + * User API * * Methods: - * void onConnect(IDSCPv2Connection) to notify the user, a new connection was created + * void connect(IDSCPv2Settings) initiate idscpv2 connect to host from settings + * SecureServer listen(IDSCPv2Settings) initiate creation of a + * void secureChannelConnectHandler(SecureChannel) * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class IDSCPv2Configuration implements IDSCPv2Callback { + private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Configuration.class); private IDSCPv2Initiator user; private DapsDriver dapsDriver; @@ -39,26 +47,40 @@ public IDSCPv2Configuration(IDSCPv2Initiator initiator, } public void connect(IDSCPv2Settings settings){ + LOG.info("Connect to an idscpv2 server ({})", settings.getHost()); secureChannelDriver.connect(settings, this); } - public SecureServer listen(IDSCPv2Settings settings){ - return secureChannelDriver.listen(settings, this); + public SecureServer listen(IDSCPv2Settings settings) throws IDSCPv2Exception { + LOG.info("Starting new IDSCPv2 server at port {}", settings.getServerPort()); + + SecureServer secureServer; + if ((secureServer = secureChannelDriver.listen(settings, this)) == null){ + throw new IDSCPv2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); + } + + return secureServer; } @Override public void secureChannelConnectHandler(SecureChannel secureChannel) { if (secureChannel == null){ - user.errorHandler("Creating Secure channel failed. Cannot create secure Channel"); + LOG.warn("IDSCPv2 connect failed because no secure channel was established"); + user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { - + LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); + LOG.debug("Send Idscp hello"); + secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() + .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) + .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); //toDo verify security properties //toDo RAT - //create new IDSCPv2Connection + LOG.debug("All IDSCPv2 requirements for new connection were fulfilled"); String connectionId = UUID.randomUUID().toString(); IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); secureChannel.registerMessageListener(newConnection); + LOG.info("A new IDSCPv2 connection with id {} was created", connectionId); user.newConnectionHandler(newConnection); } } @@ -66,20 +88,29 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { @Override public void secureChannelListenHandler(SecureChannel secureChannel) { if (secureChannel != null){ - + LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); + LOG.debug("Send Idscp hello"); + secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() + .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) + .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); //toDo verify security properties //toDo RAT + LOG.debug("All IDSCPv2 requirements for a new incoming connection were fulfilled"); //create new IDSCPv2Connection String connectionId = UUID.randomUUID().toString(); IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); secureChannel.registerMessageListener(newConnection); + LOG.info("A new idscpv2 connection with id {} was created", connectionId); user.newConnectionHandler(newConnection); + } else { + LOG.warn("An incoming idscpv2 client connection request failed because no secure channel was established"); } } @Override public void connectionClosedHandler(String connectionId) { + LOG.info("IDSCPv2 connection with id {} has been closed", connectionId); user.connectionClosedHandler(connectionId); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index 7de785e0d..8e943d931 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; /** - * IDSCPv2 configuration class, containing information about keyStore and TrustStores, Attestation Types + * IDSCPv2 configuration class, containing information about keyStore and TrustStores, Attestation Types, host, ... * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index ba1387f29..fa680dff5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -3,25 +3,26 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; - -import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * An interface for the secureChannel (e.g. TLS), which is the secure underlying basis of the IDSCPv2 protocol + * A secureChannel which is the secure underlying basis of the IDSCPv2 protocol, that implements a secureChannelListener * * Developer API * - * Constructors depends on the implementation - * * Methods: - * void close() to close the secureChannel to the other secure endpoint + * void close() to close the secureChannel * void send(IDSCPv2Message) to send an IDSCPv2Message as bytes via the secure channel * void onMessage(byte[] data) to receive new bytes via the secure channel * boolean isConnected() to check if the secure channel is still open + * void registerMessageListener(IdscpMsgListener) to register an idscpv2 message listener + * void setEndpointConnectionId(String id) to set the connectionId * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class SecureChannel implements SecureChannelListener { + private static final Logger LOG = LoggerFactory.getLogger(SecureChannel.class); private SecureChannelEndpoint endpoint; private IdscpMsgListener listener = null; @@ -31,21 +32,23 @@ public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ } public void close(){ + LOG.debug("Close secure channel"); endpoint.close(); } public void send(IdscpMessage msg){ + LOG.debug("Send idscp message via secure channel"); endpoint.send(msg.toByteArray()); } @Override public void onMessage(byte[] data){ - System.out.println(Arrays.toString(data)); + LOG.debug("New raw data were received via the secure channel"); try { IdscpMessage message = IdscpMessage.parseFrom(data); listener.onMessage(message); } catch (InvalidProtocolBufferException e) { - e.printStackTrace(); + LOG.warn("Cannot parse raw data into IdscpMessage {}", data); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index 83e08bcba..1e9528283 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -1,6 +1,19 @@ package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; - +/** + * An interface for a secureChannelEndpoint that implements functions to delegate idscp functions to the secure channel + * + * Developer API + * + * Methods: + * void close() disconnect + * void onMessage(int len, byte[]) receive new raw data from connected endpoint + * void send(byte[]) send byte array to connected endpoint + * boolean isConnected() check if endpoint is connected + * void setConnectionId(String id) + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public interface SecureChannelEndpoint { void close(); void onMessage(int len, byte[] bytes); From f168b0e726a509a64ed9d55b3a9a04b387ebd4ac Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 9 Jan 2020 17:02:28 +0100 Subject: [PATCH 032/237] Avoiding race conditions for unregistered listeners using CountDownLatch --- .../client/InputListenerThread.java | 4 +-- .../secure_channel/client/TLSClient.java | 27 +++++++++++++++---- .../secure_channel/server/TLSServer.java | 2 +- .../server/TLSServerThread.java | 19 +++++++++---- .../secure_channel/SecureChannel.java | 7 +++++ 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 98b908932..857c5c586 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -20,10 +20,10 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class InputListenerThread extends Thread implements InputListener { - private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); + //private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); private InputStream in; - private ArrayList listeners = new ArrayList<>(); + private ArrayList listeners = new ArrayList<>(); //no race conditions, could be empty list private volatile boolean running = true; public InputListenerThread(InputStream in){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 3d16fe160..1563b88b9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -18,8 +18,9 @@ import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.concurrent.CountDownLatch; - /** +/** * A TLS Client that notifies an IDSCPv2Configuration when a secure channel was created and the TLS handshake is done * The client is notified from an InputListenerThread when new data are available and transfer them to the * SecureChannelListener @@ -55,8 +56,10 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private Socket clientSocket; private OutputStream out; private InputListenerThread inputListenerThread; - private SecureChannelListener listener; - private IDSCPv2Callback callback; + private SecureChannelListener listener; //race conditions are avoided using CountDownLatch + private CountDownLatch listenerLatch = new CountDownLatch(1); + private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in constructor + private CountDownLatch connectionIdLatch = new CountDownLatch(1); private String connectionId = null; public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) @@ -156,6 +159,7 @@ private void disconnect(){ @Override public void setConnectionId(String connectionId){ this.connectionId = connectionId; + connectionIdLatch.countDown(); } @Override @@ -192,6 +196,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) LOG.debug("TLS Handshake was successful. Starting input listener thread"); SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; + listenerLatch.countDown(); inputListenerThread.start(); callback.secureChannelConnectHandler(secureChannel); } @@ -204,9 +209,21 @@ public void onMessage(int len, byte[] rawData) { //End of stream, connection is not available anymore LOG.debug("Client is terminating after server disconnected"); disconnect(); - callback.connectionClosedHandler(this.connectionId); + + try { + connectionIdLatch.await(); + callback.connectionClosedHandler(this.connectionId); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } + } else { - listener.onMessage(data); + try{ + listenerLatch.await(); + listener.onMessage(data); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index fb863aa0d..e665b8f84 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -38,7 +38,7 @@ public class TLSServer extends Thread implements SecureServer { private volatile boolean isRunning = false; private ServerSocket serverSocket; - private IDSCPv2Callback callback; + private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in the constructor public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback) throws IOException, NoSuchAlgorithmException, KeyManagementException { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index ffec566ae..348dc6b0c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -49,9 +49,10 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private volatile boolean running = true; private InputStream in; private OutputStream out; - private String connectionId; - private SecureChannelListener listener = null; - private IDSCPv2Callback callback; + private String connectionId = null; //race condition avoided using CountDownLatch + private CountDownLatch connectionIdLatch = new CountDownLatch(1); + private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch + private IDSCPv2Callback callback; // race conditions are avoided because callback is initialized by constructor private CountDownLatch listenerLatch = new CountDownLatch(1); @@ -73,6 +74,7 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene @Override public void setConnectionId(String connectionId){ this.connectionId = connectionId; + connectionIdLatch.countDown(); } @Override @@ -103,7 +105,14 @@ public void run(){ running = false; } } - callback.connectionClosedHandler(this.connectionId); + + try { + connectionIdLatch.await(); + callback.connectionClosedHandler(this.connectionId); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } + LOG.trace("ServerThread is terminating"); try { out.close(); @@ -141,7 +150,7 @@ public void onMessage(int len, byte[] rawData) { listenerLatch.await(); this.listener.onMessage(data); } catch (InterruptedException e){ - e.printStackTrace(); + Thread.currentThread().interrupt(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index fa680dff5..823dddbc2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -6,6 +6,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.CountDownLatch; + /** * A secureChannel which is the secure underlying basis of the IDSCPv2 protocol, that implements a secureChannelListener * @@ -26,6 +28,7 @@ public class SecureChannel implements SecureChannelListener { private SecureChannelEndpoint endpoint; private IdscpMsgListener listener = null; + private CountDownLatch listenerLatch = new CountDownLatch(1); public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ this.endpoint = secureChannelEndpoint; @@ -46,9 +49,12 @@ public void onMessage(byte[] data){ LOG.debug("New raw data were received via the secure channel"); try { IdscpMessage message = IdscpMessage.parseFrom(data); + listenerLatch.await(); listener.onMessage(message); } catch (InvalidProtocolBufferException e) { LOG.warn("Cannot parse raw data into IdscpMessage {}", data); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); } } @@ -58,6 +64,7 @@ public boolean isConnected(){ public void registerMessageListener(IdscpMsgListener listener){ this.listener = listener; + listenerLatch.countDown(); } public void setEndpointConnectionId(String id){ From 76a636e155967903d44d5a7363fef26196954c61 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 9 Jan 2020 18:44:48 +0100 Subject: [PATCH 033/237] Add protobuf message length --- .../client/DataAvailableListener.java | 2 +- .../client/InputListenerThread.java | 31 ++++++++------ .../secure_channel/client/TLSClient.java | 10 ++--- .../server/TLSServerThread.java | 41 +++++++++---------- .../secure_channel/SecureChannelEndpoint.java | 2 +- 5 files changed, 44 insertions(+), 42 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java index 1e8c035d6..88fdd28bc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -6,5 +6,5 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface DataAvailableListener { - void onMessage(int len, byte[] rawData); + void onMessage(byte[] data); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 857c5c586..c0678e06f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -4,6 +4,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.DataInputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.net.SocketTimeoutException; @@ -22,29 +24,32 @@ public class InputListenerThread extends Thread implements InputListener { //private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); - private InputStream in; + private DataInputStream in; private ArrayList listeners = new ArrayList<>(); //no race conditions, could be empty list private volatile boolean running = true; public InputListenerThread(InputStream in){ - this.in = in; + this.in = new DataInputStream(in); } public void run(){ - byte[] buf = new byte[2048]; + byte[] buf; while (running){ try { - int len = in.read(buf, 0, buf.length); - if (0 > len) { - notifyListeners(TlsConstants.END_OF_STREAM.length(), TlsConstants.END_OF_STREAM.getBytes()); - running = false; //terminate - } else { - notifyListeners(len, buf); - } - } catch (SocketTimeoutException e){ + + int len = in.readInt(); + buf = new byte[len]; + in.readFully(buf, 0, len); + notifyListeners(buf); + + } catch (SocketTimeoutException e) { //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye //alternative: close socket / InputStream and catch exception //continue; + //toDo offset when timeout while reading ??? + } catch (EOFException e){ + notifyListeners(TlsConstants.END_OF_STREAM.getBytes()); + running = false; //terminate } catch (IOException e) { //e.printStackTrace(); running = false; @@ -58,9 +63,9 @@ public void register(DataAvailableListener listener) { listeners.add(listener); } - private void notifyListeners(int len, byte[] bytes) { + private void notifyListeners(byte[] bytes) { for (DataAvailableListener listener : listeners){ - listener.onMessage(len, bytes); + listener.onMessage(bytes); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 1563b88b9..2f7e8e9f1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.*; +import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; @@ -54,7 +55,7 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); private Socket clientSocket; - private OutputStream out; + private DataOutputStream out; private InputListenerThread inputListenerThread; private SecureChannelListener listener; //race conditions are avoided using CountDownLatch private CountDownLatch listenerLatch = new CountDownLatch(1); @@ -119,7 +120,7 @@ public void connect(String hostname, int port){ //set clientSocket timeout to allow safeStop() clientSocket.setSoTimeout(5000); - out = clientSocket.getOutputStream(); + out = new DataOutputStream(clientSocket.getOutputStream()); //add inputListener but start it not before handshake is complete inputListenerThread = new InputListenerThread(clientSocket.getInputStream()); @@ -172,6 +173,7 @@ public void send(byte[] data){ LOG.warn("Client cannot send data because socket is not connected"); } else { try { + out.writeInt(data.length); out.write(data); out.flush(); LOG.debug("Send message: {}", new String(data)); @@ -202,9 +204,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) } @Override - public void onMessage(int len, byte[] rawData) { - byte[] data = new byte[len]; - System.arraycopy(rawData, 0, data, 0, len); + public void onMessage(byte[] data) { if ((new String(data, StandardCharsets.UTF_8)).equals(TlsConstants.END_OF_STREAM)){ //End of stream, connection is not available anymore LOG.debug("Client is terminating after server disconnected"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 348dc6b0c..c77c9bc7b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -11,10 +11,9 @@ import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocket; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.net.SocketTimeoutException; +import java.util.Arrays; import java.util.concurrent.CountDownLatch; /** @@ -47,8 +46,8 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private SSLSocket sslSocket; private volatile boolean running = true; - private InputStream in; - private OutputStream out; + private DataInputStream in; + private DataOutputStream out; private String connectionId = null; //race condition avoided using CountDownLatch private CountDownLatch connectionIdLatch = new CountDownLatch(1); private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch @@ -63,8 +62,8 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene try { //set timout for blocking read sslSocket.setSoTimeout(5000); - in = sslSocket.getInputStream(); - out = sslSocket.getOutputStream(); + in = new DataInputStream(sslSocket.getInputStream()); + out = new DataOutputStream(sslSocket.getOutputStream()); } catch (IOException e){ LOG.error(e.getMessage()); running = false; @@ -80,26 +79,25 @@ public void setConnectionId(String connectionId){ @Override public void run(){ //wait for new data while running - byte[] buf = new byte[2048]; - + byte[] buf; while (running){ try { - int len = in.read(buf, 0, buf.length); - if (0 > len) { - //onMessage(TlsConstants.END_OF_STREAM.length(), TlsConstants.END_OF_STREAM.getBytes()); - running = false; - } else { - onMessage(len, buf); - } + int len = in.readInt(); + buf = new byte[len]; + in.readFully(buf, 0, len); + onMessage(buf); + } catch (SocketTimeoutException e){ //timeout catches safeStop() call and allows to send server_goodbye //alternative: close sslSocket and catch SocketException //continue - } catch (SSLException e){ + } catch (SSLException e) { LOG.error("SSL error"); e.printStackTrace(); running = false; return; + } catch (EOFException e){ + running = false; } catch (IOException e){ e.printStackTrace(); running = false; @@ -128,12 +126,12 @@ public void send(byte[] data) { LOG.error("Server cannot send data because socket is not connected"); } else { try { + out.writeInt(data.length); out.write(data); out.flush(); LOG.trace("Send message: " + new String(data)); } catch (IOException e){ - LOG.error("Server cannot send data"); - e.printStackTrace(); + LOG.error("Server cannot send data. {}",e.getMessage()); } } } @@ -143,9 +141,8 @@ public void close() { safeStop(); } - public void onMessage(int len, byte[] rawData) { - byte[] data = new byte[len]; - System.arraycopy(rawData, 0, data, 0, len); + @Override + public void onMessage(byte[] data) { try{ listenerLatch.await(); this.listener.onMessage(data); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index 1e9528283..dd27ccf5e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -16,7 +16,7 @@ */ public interface SecureChannelEndpoint { void close(); - void onMessage(int len, byte[] bytes); + void onMessage(byte[] bytes); void send(byte[] bytes); boolean isConnected(); void setConnectionId(String id); From 865dfbe8e9f28873720c6761da163a65195c58bd Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Fri, 10 Jan 2020 11:36:10 +0100 Subject: [PATCH 034/237] FIX build error, uncatched IDSCPv2Exception in Tests --- idscp2/src/test/java/IDSCPv2ServerInitiator.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index eb76df665..d1cf61db4 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; @@ -19,7 +20,12 @@ public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, null,null,null,secureChannelDriver); - secureServer = idscpServerConfig.listen(serverSettings); + try { + secureServer = idscpServerConfig.listen(serverSettings); + } catch (IDSCPv2Exception e) { + //e.printStackTrace(); + return; + } //secureServer.safeStop(); try { Thread.sleep(300000); //run server for 5 minutes From 5616e66b0e215a66cfd21432ca2f8808f55bfbc3 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Fri, 10 Jan 2020 13:51:56 +0100 Subject: [PATCH 035/237] Add Idscpv2Server, allow multiple idscp servers within one configuration, add idscpConnection management within the idscpServer --- .../secure_channel/NativeTLSDriver.java | 6 +- .../secure_channel/server/TLSServer.java | 15 ++-- .../server/TLSServerThread.java | 15 ++-- .../interfaces/SecureChannelDriver.java | 12 ++- .../configuration/IDSCPv2Callback.java | 5 +- .../configuration/IDSCPv2Configuration.java | 15 ++-- .../idscp_server/IDSCPv2Server.java | 84 +++++++++++++++++++ .../idscp_server/IdscpConnectionListener.java | 8 ++ .../src/test/java/IDSCPv2ClientInitiator.java | 4 +- .../src/test/java/IDSCPv2ServerInitiator.java | 21 +++-- 10 files changed, 148 insertions(+), 37 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 9303d6cc0..fa95f2418 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -6,6 +6,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,9 +38,10 @@ public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { } @Override - public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback) { + public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, + IdscpConnectionListener idscpServerCallback) { try { - TLSServer tlsServer = new TLSServer(settings, callback); + TLSServer tlsServer = new TLSServer(settings, configCallback, idscpServerCallback); tlsServer.start(); return tlsServer; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index e665b8f84..bad618463 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -5,6 +5,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,11 +39,14 @@ public class TLSServer extends Thread implements SecureServer { private volatile boolean isRunning = false; private ServerSocket serverSocket; - private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in the constructor + private IDSCPv2Callback idscpConfigCallback; //no race conditions + private IdscpConnectionListener idscpServerCallback; - public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback) + public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, + IdscpConnectionListener idscpServerCallback) throws IOException, NoSuchAlgorithmException, KeyManagementException { - this.callback = callback; + this.idscpConfigCallback = configCallback; + this.idscpServerCallback = idscpServerCallback; /* init server for TCP/TLS communication */ @@ -82,7 +86,8 @@ public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback callback) sslParameters.setNeedClientAuth(true); //client must authenticate sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite - //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an other identity in the examples at the moment + //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an + // other identity in the examples at the moment //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification sslServerSocket.setSSLParameters(sslParameters); LOG.debug("TLS server was initialized successfully"); @@ -118,7 +123,7 @@ public void run(){ //start new server thread LOG.debug("New TLS client has connected. Create new server session"); - TLSServerThread server = new TLSServerThread(sslSocket, this.callback); + TLSServerThread server = new TLSServerThread(sslSocket, idscpConfigCallback, idscpServerCallback); sslSocket.addHandshakeCompletedListener(server); server.start(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index c77c9bc7b..f54e93cf5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -1,6 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -13,7 +14,6 @@ import javax.net.ssl.SSLSocket; import java.io.*; import java.net.SocketTimeoutException; -import java.util.Arrays; import java.util.concurrent.CountDownLatch; /** @@ -51,13 +51,15 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private String connectionId = null; //race condition avoided using CountDownLatch private CountDownLatch connectionIdLatch = new CountDownLatch(1); private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch - private IDSCPv2Callback callback; // race conditions are avoided because callback is initialized by constructor + private IDSCPv2Callback configCallback; //no race conditions + private IdscpConnectionListener idscpServerCallback; //no race conditions private CountDownLatch listenerLatch = new CountDownLatch(1); - TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback callback){ + TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback configCallback, IdscpConnectionListener idscpServerCallback){ this.sslSocket = sslSocket; - this.callback = callback; + this.configCallback = configCallback; + this.idscpServerCallback = idscpServerCallback; try { //set timout for blocking read @@ -106,7 +108,8 @@ public void run(){ try { connectionIdLatch.await(); - callback.connectionClosedHandler(this.connectionId); + idscpServerCallback.connectionClosedHandler(this.connectionId); + configCallback.connectionClosedHandler(this.connectionId); } catch (InterruptedException e){ Thread.currentThread().interrupt(); } @@ -165,6 +168,6 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); - callback.secureChannelListenHandler(secureChannel); + configCallback.secureChannelListenHandler(secureChannel, idscpServerCallback); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 2a1e7ea83..a480d075e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; /** * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function for IDSCPv2 clients and @@ -13,12 +14,15 @@ * void connect(IDSCPv2Settings, IDSCPv2Callback) to create an IDSCPv2 connection to the host from the settings * registers a callback for errors and return of a secure channel * - * SecureServer listen(IDSCPv2Settings, IDSCPv2Callback) to create an IDSCPv2 server configured by the IDSCPv2 settings - * registers a callback for errors and new incoming connections + * SecureServer listen(IDSCPv2Settings, IDSCPv2Callback, IdscpConnectionListener) + * + * to create an IDSCPv2 server configured by the IDSCPv2 settings registers callbacks + * for errors and new incoming connections * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface SecureChannelDriver { - void connect(IDSCPv2Settings settings, IDSCPv2Callback callback); - SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback callback); + void connect(IDSCPv2Settings settings, IDSCPv2Callback configCallback); + SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, + IdscpConnectionListener idscpServerCallback); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java index af6921d6d..230f571c0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java @@ -1,5 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; /** @@ -10,13 +11,13 @@ * * Methods: * void secureChannelConnectHandler(SecureChannel) to notify the client about a new secure channel - * void secureChannelListenHandler(SecureChannel) to notify the server about a new secure channel + * void secureChannelListenHandler(SecureChannel, IdscpConnectionListener) to notify the server about new secureChannel * void connectionClosedHandler(String connectionId) to notify listener about connection was closed * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface IDSCPv2Callback { void secureChannelConnectHandler(SecureChannel secureChannel); - void secureChannelListenHandler(SecureChannel secureChannel); + void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer); void connectionClosedHandler(String connectionId); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index 77009d352..de18f1e50 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -4,12 +4,13 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.UUID; /** @@ -51,15 +52,18 @@ public void connect(IDSCPv2Settings settings){ secureChannelDriver.connect(settings, this); } - public SecureServer listen(IDSCPv2Settings settings) throws IDSCPv2Exception { + public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { LOG.info("Starting new IDSCPv2 server at port {}", settings.getServerPort()); SecureServer secureServer; - if ((secureServer = secureChannelDriver.listen(settings, this)) == null){ + IDSCPv2Server idscpServer = new IDSCPv2Server(); + + if ((secureServer = secureChannelDriver.listen(settings, this, idscpServer)) == null){ throw new IDSCPv2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); } - return secureServer; + idscpServer.setSecureServer(secureServer); + return idscpServer; } @Override @@ -86,7 +90,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { } @Override - public void secureChannelListenHandler(SecureChannel secureChannel) { + public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); LOG.debug("Send Idscp hello"); @@ -102,6 +106,7 @@ public void secureChannelListenHandler(SecureChannel secureChannel) { IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); secureChannel.registerMessageListener(newConnection); LOG.info("A new idscpv2 connection with id {} was created", connectionId); + idscpServer.newConnectionHandler(newConnection); //bind connection to idscp server user.newConnectionHandler(newConnection); } else { LOG.warn("An incoming idscpv2 client connection request failed because no secure channel was established"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java new file mode 100644 index 000000000..ac5aad82b --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java @@ -0,0 +1,84 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; + +public class IDSCPv2Server implements IdscpConnectionListener{ + private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); + + private SecureServer secureServer; //no race conditions using CountDownLatch + private CountDownLatch secureServerLatch = new CountDownLatch(1); + private ConcurrentHashMap connections = new ConcurrentHashMap<>(); + + public IDSCPv2Server(){ + + } + + public IDSCPv2Server(SecureServer secureServer){ + this.secureServer = secureServer; + secureServerLatch.countDown(); + } + + public void terminate(){ + LOG.info("Terminating idscp server {}", this.toString()); + try { + secureServerLatch.await(); + secureServer.safeStop(); + terminateAllSessions(); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } + } + + public void terminateAllSessions(){ + for (IDSCPv2Connection c : connections.values()){ + if (c.isConnected()){ + c.close(); + LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); + } + connections.remove(c.getConnectionId()); + } + } + + public boolean isRunning(){ + try { + secureServerLatch.await(); + return secureServer.isRunning(); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } + return false; + } + + public IDSCPv2Connection getConnectionById(String connectionId){ + return connections.get(connectionId); + } + + public List getAllConnections(){ + return new ArrayList<>(connections.values()); + } + + @Override + public void newConnectionHandler(IDSCPv2Connection connection) { + LOG.debug("Binding new idscpv2 connection to server {}", this.toString()); + connections.put(connection.getConnectionId(), connection); + } + + @Override + public void connectionClosedHandler(String connectionId) { + LOG.debug("Removing connection with id {} from server storage", connectionId); + connections.remove(connectionId); + } + + public void setSecureServer(SecureServer secureServer) { + this.secureServer = secureServer; + secureServerLatch.countDown(); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java new file mode 100644 index 000000000..2857b7ebd --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java @@ -0,0 +1,8 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; + +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; + +public interface IdscpConnectionListener { + void newConnectionHandler(IDSCPv2Connection connection); + void connectionClosedHandler(String connectionId); +} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index d00d0d06a..13694a6d0 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -22,12 +22,12 @@ public void init(IDSCPv2Settings settings){ @Override public void newConnectionHandler(IDSCPv2Connection connection) { this.connections.put(connection.getConnectionId(), connection); - connection.close(); + //connection.close(); } @Override public void errorHandler(String error) { - System.out.println(error); + System.out.println("Error occurred: " + error); } @Override diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index d1cf61db4..2023d7cc8 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,9 +1,9 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; @@ -12,42 +12,41 @@ public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { - private ConcurrentHashMap connections = new ConcurrentHashMap<>(); - private SecureServer secureServer = null; - + //private ConcurrentHashMap connections = new ConcurrentHashMap<>(); public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, null,null,null,secureChannelDriver); + IDSCPv2Server idscPv2Server; try { - secureServer = idscpServerConfig.listen(serverSettings); + idscPv2Server = idscpServerConfig.listen(serverSettings); } catch (IDSCPv2Exception e) { //e.printStackTrace(); return; } //secureServer.safeStop(); try { - Thread.sleep(300000); //run server for 5 minutes + Thread.sleep(40000); //run server for 5 minutes } catch (Exception e){ } - secureServer.safeStop(); + idscPv2Server.terminate(); } @Override public void newConnectionHandler(IDSCPv2Connection connection) { - connections.put(connection.getConnectionId(), connection); + //connections.put(connection.getConnectionId(), connection); } @Override public void errorHandler(String error) { - + System.out.println("Error occurred: " + error); } @Override public void connectionClosedHandler(String connectionId) { - System.out.println("Connection closed"); - connections.remove(connectionId); + System.out.println("Connection with id " + connectionId + " has been closed"); + //connections.remove(connectionId); } } From 3d2d2ac732f6f1c3a6eb170c7890edafdf2fda47 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Fri, 10 Jan 2020 16:12:23 +0100 Subject: [PATCH 036/237] WIP: Add finite state machine --- .../configuration/IDSCPv2Configuration.java | 23 ++++--- .../finite_state_machine/Event.java | 4 ++ .../idscp_core/finite_state_machine/FSM.java | 65 +++++++++++++++++++ .../finite_state_machine/State.java | 4 ++ .../finite_state_machine/Transition.java | 13 ++++ .../secure_channel/SecureChannel.java | 40 ++++++++++-- 6 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index de18f1e50..ed60ce0d1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -73,12 +73,11 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); - LOG.debug("Send Idscp hello"); - secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() - .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) - .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); - //toDo verify security properties - //toDo RAT + try { + secureChannel.startIdscpHandshake(); + } catch (IDSCPv2Exception e){ + return; + } LOG.debug("All IDSCPv2 requirements for new connection were fulfilled"); String connectionId = UUID.randomUUID().toString(); @@ -93,12 +92,12 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); - LOG.debug("Send Idscp hello"); - secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() - .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) - .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); - //toDo verify security properties - //toDo RAT + + try { + secureChannel.startIdscpHandshake(); + } catch (IDSCPv2Exception e){ + return; + } LOG.debug("All IDSCPv2 requirements for a new incoming connection were fulfilled"); //create new IDSCPv2Connection diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java new file mode 100644 index 000000000..e32d25009 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -0,0 +1,4 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public class Event { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java new file mode 100644 index 000000000..26d075d24 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -0,0 +1,65 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCPv2.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CountDownLatch; + +public class FSM { + private static final Logger LOG = LoggerFactory.getLogger(FSM.class); + + /* ----------- IDSCPv2 Protocol States ---------- */ + private static final State STATE_CLOSED = new State(); + private static final State STATE_WAIT_FOR_HELLO = new State(); + private static final State STATE_LISTEN = new State(); + private static final State STATE_WAIT_FOR_RAT = new State(); + private static final State STATE_WAIT_FOR_RAT_CLIENT = new State(); + private static final State STATE_WAIT_FOR_RAT_SERVER = new State(); + private static final State STATE_WAIT_FOR_DAT_AND_RAT_CLIENT = new State(); + private static final State STATE_WAIT_FOR_DAT_AND_RAT_SERVER = new State(); + private static final State STATE_ESTABLISHED = new State(); + /* ---------------- end of states --------------- */ + + + /* ----------- IDSCPv2 Protocol Transitions ---------- */ + + /* ---------------- end of transitions --------------- */ + + private State currentState; + private SecureChannel secureChannel; + private CountDownLatch handshakeComplete = new CountDownLatch(1); + + public FSM(SecureChannel secureChannel){ + this.secureChannel = secureChannel; + currentState = STATE_ESTABLISHED; + } + + public void start(){ + LOG.debug("Send IDSCP_HELLO"); + secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() + .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) + .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); + //toDo verify security properties + //toDo RAT + handshakeComplete.countDown(); + } + + public void delegate(IdscpMessage msg){ + + } + + private void send(IdscpMessage msg){ + secureChannel.send(msg); + } + + public boolean isConnected(){ + return currentState.equals(STATE_ESTABLISHED); + } + + public CountDownLatch getHandshakeComplete() { + return handshakeComplete; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java new file mode 100644 index 000000000..2c1385ae1 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -0,0 +1,4 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public class State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java new file mode 100644 index 000000000..94a53346a --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java @@ -0,0 +1,13 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public class Transition { + + private final State startState; + private final State endState; + + public Transition(State startState, State endState){ + this.startState = startState; + this.endState = endState; + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index 823dddbc2..de49659a1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -1,8 +1,10 @@ package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; import com.google.protobuf.InvalidProtocolBufferException; +import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; +import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,13 +31,14 @@ public class SecureChannel implements SecureChannelListener { private SecureChannelEndpoint endpoint; private IdscpMsgListener listener = null; private CountDownLatch listenerLatch = new CountDownLatch(1); + private FSM fsm; public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ this.endpoint = secureChannelEndpoint; + this.fsm = new FSM(this); } public void close(){ - LOG.debug("Close secure channel"); endpoint.close(); } @@ -49,10 +52,20 @@ public void onMessage(byte[] data){ LOG.debug("New raw data were received via the secure channel"); try { IdscpMessage message = IdscpMessage.parseFrom(data); - listenerLatch.await(); - listener.onMessage(message); + if (fsm.isConnected()){ + listenerLatch.await(); + listener.onMessage(message); + } else { + fsm.delegate(message); + } } catch (InvalidProtocolBufferException e) { - LOG.warn("Cannot parse raw data into IdscpMessage {}", data); + LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); + send( + IdscpMessage.newBuilder() + .setType(IdscpMessage.Type.IDSCP_ERROR) + .setIdscpError(IdscpError.newBuilder().setErrorMsg("Cannot parse raw data into IdscpMessage")) + .build() + ); } catch (InterruptedException e){ Thread.currentThread().interrupt(); } @@ -70,4 +83,21 @@ public void registerMessageListener(IdscpMsgListener listener){ public void setEndpointConnectionId(String id){ this.endpoint.setConnectionId(id); } + + public void startIdscpHandshake() throws IDSCPv2Exception { + fsm.start(); + try { + fsm.getHandshakeComplete().await(); + } catch (InterruptedException e) { + throw new IDSCPv2Exception("IDSCPv2 handshake failed"); + } + + if (!fsm.isConnected()){ + throw new IDSCPv2Exception("IDSCPv2 handshake failed"); + } + + LOG.info("Idscpv2 handshake successful"); + } + + } From 8542d4337558021a4db0e094b4edbe7261e5dda9 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 13 Jan 2020 15:56:09 +0100 Subject: [PATCH 037/237] Add FSM as unique layer between IDSCPv2 and secure channel --- .../secure_channel/client/TLSClient.java | 2 +- .../server/TLSServerThread.java | 7 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 22 ++--- .../configuration/IDSCPv2Configuration.java | 26 +++--- .../idscp_core/finite_state_machine/FSM.java | 88 ++++++++++++++++--- .../finite_state_machine/FsmListener.java | 5 ++ .../secure_channel/SecureChannel.java | 59 +++---------- .../src/test/java/IDSCPv2ServerInitiator.java | 2 +- 8 files changed, 123 insertions(+), 88 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 2f7e8e9f1..13b99667b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -61,7 +61,7 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private CountDownLatch listenerLatch = new CountDownLatch(1); private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in constructor private CountDownLatch connectionIdLatch = new CountDownLatch(1); - private String connectionId = null; + private String connectionId = "empty_connection_id"; public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) throws IOException, KeyManagementException, NoSuchAlgorithmException{ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index f54e93cf5..fad3f9190 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -48,7 +48,7 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private volatile boolean running = true; private DataInputStream in; private DataOutputStream out; - private String connectionId = null; //race condition avoided using CountDownLatch + private String connectionId = "empty_connection_id"; //race condition avoided using CountDownLatch private CountDownLatch connectionIdLatch = new CountDownLatch(1); private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch private IDSCPv2Callback configCallback; //no race conditions @@ -97,12 +97,15 @@ public void run(){ LOG.error("SSL error"); e.printStackTrace(); running = false; + connectionIdLatch.countDown(); return; } catch (EOFException e){ running = false; + connectionIdLatch.countDown(); } catch (IOException e){ e.printStackTrace(); running = false; + connectionIdLatch.countDown(); } } @@ -120,7 +123,7 @@ public void run(){ in.close(); sslSocket.close(); } catch (IOException e) { - e.printStackTrace(); + //e.printStackTrace(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index a1eb0f4cf..69761bd38 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -1,5 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpClose; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; @@ -22,30 +23,21 @@ public class IDSCPv2Connection implements IdscpMsgListener { private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Connection.class); - private SecureChannel secureChannel; + private FSM fsm; private String connectionId; - public IDSCPv2Connection(SecureChannel secureChannel, String connectionId){ - this.secureChannel = secureChannel; + public IDSCPv2Connection(FSM fsm, String connectionId){ + this.fsm = fsm; this.connectionId = connectionId; - secureChannel.setEndpointConnectionId(connectionId); } public void close() { - LOG.info("Close idscp connection"); - LOG.debug("Send IDSCP_CLOSE"); - IdscpMessage msg = IdscpMessage.newBuilder() - .setType(IdscpMessage.Type.IDSCP_CLOSE) - .setIdscpClose(IdscpClose.newBuilder().build() - ).build(); - send(msg); - LOG.debug("Close secure channel"); - secureChannel.close(); + fsm.terminate(); } public void send(IdscpMessage msg) { LOG.debug("Send idscp message of type {}", msg.getType()); - secureChannel.send(msg); + fsm.send(msg); } @Override @@ -54,7 +46,7 @@ public void onMessage(IdscpMessage msg) { } public boolean isConnected() { - return secureChannel.isConnected(); + return fsm.isConnected(); } public String getConnectionId() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index ed60ce0d1..af08a409d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -4,6 +4,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; @@ -73,16 +74,19 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); + FSM fsm = new FSM(secureChannel, ratProverDriver, ratVerifierDriver, dapsDriver); + String connectionId = UUID.randomUUID().toString(); + //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock + fsm.setEndpointConnectionId(connectionId); + try { - secureChannel.startIdscpHandshake(); + fsm.startIdscpHandshake(); //blocking until handshake is done } catch (IDSCPv2Exception e){ return; } - LOG.debug("All IDSCPv2 requirements for new connection were fulfilled"); - String connectionId = UUID.randomUUID().toString(); - IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); - secureChannel.registerMessageListener(newConnection); + IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId); + fsm.registerMessageListener(newConnection); LOG.info("A new IDSCPv2 connection with id {} was created", connectionId); user.newConnectionHandler(newConnection); } @@ -92,18 +96,20 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); + FSM fsm = new FSM(secureChannel, ratProverDriver, ratVerifierDriver, dapsDriver); + String connectionId = UUID.randomUUID().toString(); + //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock + fsm.setEndpointConnectionId(connectionId); try { - secureChannel.startIdscpHandshake(); + fsm.startIdscpHandshake(); //blocking until handshake is done } catch (IDSCPv2Exception e){ return; } - LOG.debug("All IDSCPv2 requirements for a new incoming connection were fulfilled"); //create new IDSCPv2Connection - String connectionId = UUID.randomUUID().toString(); - IDSCPv2Connection newConnection = new IDSCPv2Connection(secureChannel, connectionId); - secureChannel.registerMessageListener(newConnection); + IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId); + fsm.registerMessageListener(newConnection); LOG.info("A new idscpv2 connection with id {} was created", connectionId); idscpServer.newConnectionHandler(newConnection); //bind connection to idscp server user.newConnectionHandler(newConnection); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 26d075d24..ad8b5cfa5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -1,5 +1,12 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import com.google.protobuf.InvalidProtocolBufferException; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2; import de.fhg.aisec.ids.messages.IDSCPv2.*; @@ -8,7 +15,7 @@ import java.util.concurrent.CountDownLatch; -public class FSM { +public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); /* ----------- IDSCPv2 Protocol States ---------- */ @@ -30,36 +37,93 @@ public class FSM { private State currentState; private SecureChannel secureChannel; - private CountDownLatch handshakeComplete = new CountDownLatch(1); + private RatProverDriver ratProverDriver; + private RatVerifierDriver ratVerifierDriver; + private DapsDriver dapsDriver; + private IdscpMsgListener listener = null; + private CountDownLatch listenerLatch = new CountDownLatch(1); + + public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, + DapsDriver dapsDriver){ - public FSM(SecureChannel secureChannel){ this.secureChannel = secureChannel; - currentState = STATE_ESTABLISHED; + secureChannel.setFsm(this); + + this.ratProverDriver = ratProver; + this.ratVerifierDriver = ratVerifier; + this.dapsDriver = dapsDriver; + + currentState = STATE_CLOSED; //start state } - public void start(){ + public void startIdscpHandshake() throws IDSCPv2Exception { LOG.debug("Send IDSCP_HELLO"); - secureChannel.send(IDSCPv2.IdscpMessage.newBuilder() + send(IDSCPv2.IdscpMessage.newBuilder() .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); //toDo verify security properties //toDo RAT - handshakeComplete.countDown(); + LOG.debug("All security requirements are fulfilled for new idscp connection"); + currentState = STATE_ESTABLISHED; } - public void delegate(IdscpMessage msg){ + public void send(IdscpMessage msg){ + secureChannel.send(msg.toByteArray()); + } + public void sendError(String msg, String code){ + IdscpMessage idscpMessage = IdscpMessage.newBuilder() + .setType(IdscpMessage.Type.IDSCP_ERROR) + .setIdscpError( + IdscpError.newBuilder() + .setErrorMsg(msg) + .setErrorCode(code) + ).build(); + send(idscpMessage); } - private void send(IdscpMessage msg){ - secureChannel.send(msg); + @Override + public void onMessage(byte[] data){ + try { + IdscpMessage message = IdscpMessage.parseFrom(data); + //toDo trigger event + if (message.getType().equals(IdscpMessage.Type.IDSCP_DATA) && currentState.equals(STATE_ESTABLISHED)){ + listenerLatch.await(); + listener.onMessage(message); + } else { + //toDo fsm logic + } + + } catch (InvalidProtocolBufferException e) { + LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); + sendError("Cannot parse raw data into IdscpMessage", ""); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); + } + } + + public void terminate(){ + LOG.info("Close idscp connection"); + LOG.debug("Send IDSCP_CLOSE"); + IdscpMessage msg = IdscpMessage.newBuilder() + .setType(IdscpMessage.Type.IDSCP_CLOSE) + .setIdscpClose(IdscpClose.newBuilder().build() + ).build(); + send(msg); + LOG.debug("Close secure channel"); + secureChannel.close(); } public boolean isConnected(){ return currentState.equals(STATE_ESTABLISHED); } - public CountDownLatch getHandshakeComplete() { - return handshakeComplete; + public void registerMessageListener(IdscpMsgListener listener){ + this.listener = listener; + listenerLatch.countDown(); + } + + public void setEndpointConnectionId(String id){ + this.secureChannel.setEndpointConnectionId(id); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java new file mode 100644 index 000000000..e797aa3cc --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -0,0 +1,5 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public interface FsmListener { + void onMessage(byte[] data); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index de49659a1..917a37f95 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -1,10 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; -import com.google.protobuf.InvalidProtocolBufferException; -import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.messages.IDSCPv2.*; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,43 +25,28 @@ public class SecureChannel implements SecureChannelListener { private static final Logger LOG = LoggerFactory.getLogger(SecureChannel.class); private SecureChannelEndpoint endpoint; - private IdscpMsgListener listener = null; - private CountDownLatch listenerLatch = new CountDownLatch(1); - private FSM fsm; + private CountDownLatch fsmLatch = new CountDownLatch(1); + private FsmListener fsm = null; public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ this.endpoint = secureChannelEndpoint; - this.fsm = new FSM(this); } public void close(){ endpoint.close(); } - public void send(IdscpMessage msg){ - LOG.debug("Send idscp message via secure channel"); - endpoint.send(msg.toByteArray()); + public void send(byte[] msg){ + LOG.debug("Send message via secure channel"); + endpoint.send(msg); } @Override public void onMessage(byte[] data){ LOG.debug("New raw data were received via the secure channel"); try { - IdscpMessage message = IdscpMessage.parseFrom(data); - if (fsm.isConnected()){ - listenerLatch.await(); - listener.onMessage(message); - } else { - fsm.delegate(message); - } - } catch (InvalidProtocolBufferException e) { - LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); - send( - IdscpMessage.newBuilder() - .setType(IdscpMessage.Type.IDSCP_ERROR) - .setIdscpError(IdscpError.newBuilder().setErrorMsg("Cannot parse raw data into IdscpMessage")) - .build() - ); + fsmLatch.await(); + fsm.onMessage(data); } catch (InterruptedException e){ Thread.currentThread().interrupt(); } @@ -75,29 +56,13 @@ public boolean isConnected(){ return endpoint.isConnected(); } - public void registerMessageListener(IdscpMsgListener listener){ - this.listener = listener; - listenerLatch.countDown(); - } - public void setEndpointConnectionId(String id){ this.endpoint.setConnectionId(id); + //deadlock is resolved } - public void startIdscpHandshake() throws IDSCPv2Exception { - fsm.start(); - try { - fsm.getHandshakeComplete().await(); - } catch (InterruptedException e) { - throw new IDSCPv2Exception("IDSCPv2 handshake failed"); - } - - if (!fsm.isConnected()){ - throw new IDSCPv2Exception("IDSCPv2 handshake failed"); - } - - LOG.info("Idscpv2 handshake successful"); + public void setFsm(FsmListener fsm) { + this.fsm = fsm; + fsmLatch.countDown(); } - - } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 2023d7cc8..94c726704 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -29,7 +29,7 @@ public void init(IDSCPv2Settings serverSettings) { try { Thread.sleep(40000); //run server for 5 minutes } catch (Exception e){ - + return; } idscPv2Server.terminate(); } From 6ef9be0e4b8371bc3e14ae1d6c5f54413a5ccbf9 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Wed, 15 Jan 2020 18:28:07 +0100 Subject: [PATCH 038/237] add idscp message factory --- .../idscp_core/IdscpMessageFactory.java | 87 +++++++++++++++++++ .../InternalControlMessage.java | 4 + .../finite_state_machine/Transition.java | 13 --- 3 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java new file mode 100644 index 000000000..d284cfd4f --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -0,0 +1,87 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +import com.google.protobuf.ByteString; +import de.fhg.aisec.ids.messages.IDSCPv2.*; + +import java.util.Arrays; + +public class IdscpMessageFactory { + + public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ + IdscpDat idscpDat = IdscpDat.newBuilder() + .setToken(ByteString.copyFrom(dat)) + .build(); + + IdscpHello idscpHello = IdscpHello.newBuilder() + .setVersion(2) + .setDynamicAttributeToken(idscpDat) + .addAllExpectedRatSuite(Arrays.asList(expectedRatSuite)) + .addAllSupportedRatSuite(Arrays.asList(supportedRatSuite)) + .build(); + + return IdscpMessage.newBuilder() + .setType(IdscpMessage.Type.IDSCP_HELLO) + .setIdscpHello(idscpHello) + .build(); + } + + public static IdscpMessage getIdscpCloseMessage(){ + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_CLOSE) + .setIdscpClose(IdscpClose.newBuilder().build()) + .build(); + } + + public static IdscpMessage getIdscpErrorMessage(String msg, String code){ + IdscpError idscpError = IdscpError.newBuilder() + .setErrorMsg(msg) + .setErrorCode(code) + .build(); + + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_ERROR) + .setIdscpError(idscpError) + .build(); + } + + public static IdscpMessage getIdscpDatExpiredMessage(){ + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_DAT_EXPIRED) + .setIdscpDatExpired(IdscpDatExpired.newBuilder().build()) + .build(); + } + + public static IdscpMessage getIdscpDatMessage(byte[] dat){ + IdscpDat idscpDat = IdscpDat.newBuilder() + .setToken(ByteString.copyFrom(dat)) + .build(); + + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_DAT) + .setIdscpDat(idscpDat) + .build(); + } + + public static IdscpMessage getIdscpReRatMessage(String cause){ + IdscpReRat idscpReRat = IdscpReRat.newBuilder() + .setCause(cause) + .build(); + + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_RE_RAT) + .setIdscpReRat(idscpReRat) + .build(); + } + + public static IdscpMessage getIdscpDataMessage(byte[] data){ + IdscpData idscpData = IdscpData.newBuilder() + .setData(ByteString.copyFrom(data)) + .build(); + + return IdscpMessage.newBuilder() + . setType(IdscpMessage.Type.IDSCP_DATA) + .setIdscpData(idscpData) + .build(); + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java new file mode 100644 index 000000000..beaa0a33a --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -0,0 +1,4 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public enum InternalControlMessage { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java deleted file mode 100644 index 94a53346a..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; - -public class Transition { - - private final State startState; - private final State endState; - - public Transition(State startState, State endState){ - this.startState = startState; - this.endState = endState; - } - -} From 4682e1ef130ee1b86e01aababfb6acc93eae5778 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Wed, 15 Jan 2020 18:29:55 +0100 Subject: [PATCH 039/237] WIP: FSM, add states, implementation for 3 states --- .../finite_state_machine/Event.java | 42 +++ .../idscp_core/finite_state_machine/FSM.java | 355 +++++++++++++++--- .../finite_state_machine/FsmListener.java | 1 + .../InternalControlMessage.java | 11 + .../finite_state_machine/State.java | 12 + 5 files changed, 365 insertions(+), 56 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index e32d25009..ce3e4a36d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -1,4 +1,46 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import de.fhg.aisec.ids.messages.IDSCPv2.*; + public class Event { + public enum EventType { + IDSCP_MESSAGE, + INTERNAL_CONTROL_MESSAGE + } + + private Object key; + private EventType type; + private IdscpMessage idscpMessage; + private InternalControlMessage controlMessage; + + public Event(Object key, InternalControlMessage controlMessage){ + this.key = key; + this.type = EventType.INTERNAL_CONTROL_MESSAGE; + this.controlMessage = controlMessage; + this.idscpMessage = null; + } + + public Event (Object key, IdscpMessage idscpMessage){ + this.key = key; + this.type = EventType.IDSCP_MESSAGE; + this.idscpMessage = idscpMessage; + this.controlMessage = null; + } + + + public Object getKey() { + return key; + } + + public EventType getType() { + return type; + } + + public IdscpMessage getIdscpMessage() { + return idscpMessage; + } + + public InternalControlMessage getControlMessage() { + return controlMessage; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index ad8b5cfa5..83bd9f3a5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -5,11 +5,11 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCPv2; import de.fhg.aisec.ids.messages.IDSCPv2.*; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.Event.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,52 +19,316 @@ public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); /* ----------- IDSCPv2 Protocol States ---------- */ - private static final State STATE_CLOSED = new State(); - private static final State STATE_WAIT_FOR_HELLO = new State(); - private static final State STATE_LISTEN = new State(); - private static final State STATE_WAIT_FOR_RAT = new State(); - private static final State STATE_WAIT_FOR_RAT_CLIENT = new State(); - private static final State STATE_WAIT_FOR_RAT_SERVER = new State(); - private static final State STATE_WAIT_FOR_DAT_AND_RAT_CLIENT = new State(); - private static final State STATE_WAIT_FOR_DAT_AND_RAT_SERVER = new State(); - private static final State STATE_ESTABLISHED = new State(); + private final State STATE_CLOSED = new State(); + private final State STATE_WAIT_FOR_HELLO = new State(); + private final State STATE_WAIT_FOR_RAT= new State(); + private final State STATE_WAIT_FOR_RAT_CLIENT = new State(); + private final State STATE_WAIT_FOR_RAT_SERVER = new State(); + private final State STATE_WAIT_FOR_DAT_AND_RAT_CLIENT = new State(); + private final State STATE_WAIT_FOR_DAT_AND_RAT_SERVER = new State(); + private final State STATE_ESTABLISHED = new State(); /* ---------------- end of states --------------- */ - /* ----------- IDSCPv2 Protocol Transitions ---------- */ - - /* ---------------- end of transitions --------------- */ - private State currentState; + private final State initialState = STATE_CLOSED; private SecureChannel secureChannel; private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; private DapsDriver dapsDriver; private IdscpMsgListener listener = null; - private CountDownLatch listenerLatch = new CountDownLatch(1); + private final CountDownLatch listenerLatch = new CountDownLatch(1); + private IdscpMessage cachedIdscpHello = null; + private final Object idscpHandshakeLock = new Object(); + private final Object fsmIsBusy = new Object(); public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, DapsDriver dapsDriver){ this.secureChannel = secureChannel; - secureChannel.setFsm(this); - this.ratProverDriver = ratProver; this.ratVerifierDriver = ratVerifier; this.dapsDriver = dapsDriver; + secureChannel.setFsm(this); + + /* ----------- Protocol Transitions ---------- */ + + STATE_CLOSED.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + * INTERNAL_CONTROL_MESSAGE.START_IDSCP_HANDSHAKE ---> send IDSCP_HELLO ---> STATE_WAIT_FOR_HELLO + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_MESSAGE.IDSCP_HELLO ---> cache IDSCP_HELLO ---> STATE_CLOSED + * ALL_OTHER_MESSAGES ---> STATE_CLOSED + */ + e -> { + LOG.debug("STATE_CLOSED triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + if (e.getControlMessage().equals(InternalControlMessage.START_IDSCP_HANDSHAKE)){ + LOG.debug("Get DAT Token vom DAT_DRIVER"); + //toDo this.dapsDriver.getToken(); + LOG.debug("Send idscp hello"); + IdscpMessage idscpHello = IdscpMessageFactory. + getIdscpHelloMessage(new byte[]{}, new String[] {"a", "b"}, new String[] {"a", "b"}); + this.send(idscpHello); + //toDo set handshake timeout + LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); + return STATE_WAIT_FOR_HELLO; + } + } else { /* IDSCP_MESSAGE */ + if (e.getIdscpMessage().hasIdscpHello()){ + LOG.debug("Cache idscp hello message"); + this.cachedIdscpHello = e.getIdscpMessage(); + } + } + + LOG.debug("Stay in state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return this.STATE_CLOSED; + } + ); + + STATE_WAIT_FOR_HELLO.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send idscp close ---> STATE_CLOSED + * IDSCP_CLOSE ---> STATE_CLOSED + * toDo IDSCP_HELLO ---> DAT Verification failed: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_HELLO ---> verify DAT, set DAT Timeout, start RAT P&V ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> STATE_WAIT_FOR_HELLO + */ + e -> { + LOG.debug("STATE_WAIT_FOR_HELLO triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + if (e.getControlMessage().equals(InternalControlMessage.ERROR)){ + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + + if (e.getControlMessage().equals(InternalControlMessage.IDSCP_STOP)){ + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + } else { //IDSCP_MESSAGE + if (e.getIdscpMessage().hasIdscpClose()){ + LOG.debug(""); + } else if (e.getIdscpMessage().hasIdscpHello()) { + LOG.debug("Verify received DAT"); + //toDo Dat verification + //toDo set DAT timeout + //toDo start RAT_PROVER + //toDo start RAT_VERIFIER + LOG.debug("Switch to state STATE_ESTABLISHED"); + notifyHandshakeCompleteLock(); + return STATE_ESTABLISHED; + } + } + LOG.debug("Stay in state STATE_WAIT_FOR_HELLO"); + return this.STATE_WAIT_FOR_HELLO; + } + ); + + STATE_WAIT_FOR_RAT.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + */ + e -> { + LOG.debug("STATE_WAIT_FOR_RAT triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + + } else { //IDSCP_MESSAGE + + } + return this.STATE_WAIT_FOR_RAT; + } + ); + + STATE_WAIT_FOR_RAT_CLIENT.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + */ + e -> { + LOG.debug("STATE_WAIT_FOR_RAT_CLIENT triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + + } else { //IDSCP_MESSAGE + + } + return this.STATE_WAIT_FOR_RAT_CLIENT; + } + ); + + STATE_WAIT_FOR_RAT_SERVER.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + */ + e -> { + LOG.debug("STATE_WAIT_FOR_RAT_SERVER triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + + } else { //IDSCP_MESSAGE + + } + return this.STATE_WAIT_FOR_RAT_SERVER; + } + ); + + STATE_WAIT_FOR_DAT_AND_RAT_CLIENT.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + */ + e -> { + LOG.debug("STATE_WAIT_FOR_DAT_AND_RAT_CLIENT triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + + } else { //IDSCP_MESSAGE + + } + return STATE_WAIT_FOR_DAT_AND_RAT_CLIENT; + } + ); + + STATE_WAIT_FOR_DAT_AND_RAT_SERVER.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + */ + e -> { + LOG.debug("STATE_WAIT_FOR_DAT_AND_RAT_SERVER triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + + } else { //IDSCP_MESSAGE + + } + return STATE_WAIT_FOR_DAT_AND_RAT_SERVER; + } + ); + + STATE_ESTABLISHED.setEventHandler( + /*-------------------------------- + * Transition description + * -------------------------------- + * INTERNAL_CONTROL_MESSAGE.ERROR ---> send idscp error, send idscp close ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send idscp close ---> STATE_CLOSED + * toDo INTERNAL_CONTROL_MESSAGE.DAT_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT + * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED + * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED + */ + e -> { + LOG.debug("STATE_ESTABLISHED triggered"); + if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + if (e.getControlMessage().equals(InternalControlMessage.ERROR)){ + LOG.debug("Error occurred, send IDSCP_ERROR and IDSCP_CLOSE and close idscp connection"); + send(IdscpMessageFactory.getIdscpErrorMessage("Error occurred", "")); + send(IdscpMessageFactory.getIdscpCloseMessage()); + return STATE_CLOSED; + } else if (e.getControlMessage().equals(InternalControlMessage.IDSCP_STOP)){ + send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("Close idscp connection and send IDSCP_CLOSE"); + return STATE_CLOSED; + } + } else { //IDSCP_MESSAGE + IdscpMessage message = e.getIdscpMessage(); + if (message.hasIdscpData()){ + try { + this.listenerLatch.await(); + this.listener.onMessage(message); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } else if (message.hasIdscpClose()){ + LOG.debug("Receive IDSCP_CLOSED"); + try { + this.listenerLatch.await(); + this.listener.onMessage(message); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + LOG.debug("Switch to STATE_CLOSED"); + return STATE_CLOSED; + } + } + LOG.debug("Stay in STATE_ESTABLISHED"); + return STATE_ESTABLISHED; + } + ); + + /* ---------------- end of transitions --------------- */ + + //set initial state + currentState = initialState; + } + + @Override + public void onMessage(byte[] data){ + //parse message and create new IDSCP Message Event, then pass it to current state and update new state + try { + IdscpMessage message = IdscpMessage.parseFrom(data); + Event e = new Event(null, message); + synchronized (fsmIsBusy){ + currentState = currentState.feedEvent(e); + } + } catch (InvalidProtocolBufferException e) { + LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); + sendError("Cannot parse raw data into IdscpMessage", ""); + } + } - currentState = STATE_CLOSED; //start state + @Override + public void onControlMessage(InternalControlMessage controlMessage) { + //create Internal Control Message Event and pass it to current state and update new state + Event e = new Event(null, controlMessage); + synchronized (fsmIsBusy){ + currentState = currentState.feedEvent(e); + } + } + + public void terminate(){ + LOG.info("Close idscp connection"); + onControlMessage(InternalControlMessage.IDSCP_STOP); + LOG.debug("Close secure channel"); + secureChannel.close(); } public void startIdscpHandshake() throws IDSCPv2Exception { - LOG.debug("Send IDSCP_HELLO"); - send(IDSCPv2.IdscpMessage.newBuilder() - .setType(IDSCPv2.IdscpMessage.Type.IDSCP_HELLO) - .setIdscpHello(IDSCPv2.IdscpHello.newBuilder().build()).build()); - //toDo verify security properties - //toDo RAT - LOG.debug("All security requirements are fulfilled for new idscp connection"); - currentState = STATE_ESTABLISHED; + if (currentState.equals(STATE_CLOSED)){ + //trigger handshake init + onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); + + //check if a idscpHello was already received and trigger next transition + if (cachedIdscpHello != null){ + Event e = new Event(null, cachedIdscpHello); + synchronized (fsmIsBusy){ + currentState = currentState.feedEvent(e); + } + } + + try { + //wait until handshake was successful or failed + synchronized (idscpHandshakeLock) { + idscpHandshakeLock.wait(); + } + + if (!isConnected()){ + //handshake failed, throw exception + throw new IDSCPv2Exception("Handshake failed"); + } + + } catch (InterruptedException e) { + throw new IDSCPv2Exception("Handshake failed because thread was interrupted"); + } + } } public void send(IdscpMessage msg){ @@ -82,37 +346,10 @@ public void sendError(String msg, String code){ send(idscpMessage); } - @Override - public void onMessage(byte[] data){ - try { - IdscpMessage message = IdscpMessage.parseFrom(data); - //toDo trigger event - if (message.getType().equals(IdscpMessage.Type.IDSCP_DATA) && currentState.equals(STATE_ESTABLISHED)){ - listenerLatch.await(); - listener.onMessage(message); - } else { - //toDo fsm logic - } - - } catch (InvalidProtocolBufferException e) { - LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); - sendError("Cannot parse raw data into IdscpMessage", ""); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } + private void reset(){ + this.currentState = initialState; } - public void terminate(){ - LOG.info("Close idscp connection"); - LOG.debug("Send IDSCP_CLOSE"); - IdscpMessage msg = IdscpMessage.newBuilder() - .setType(IdscpMessage.Type.IDSCP_CLOSE) - .setIdscpClose(IdscpClose.newBuilder().build() - ).build(); - send(msg); - LOG.debug("Close secure channel"); - secureChannel.close(); - } public boolean isConnected(){ return currentState.equals(STATE_ESTABLISHED); @@ -126,4 +363,10 @@ public void registerMessageListener(IdscpMsgListener listener){ public void setEndpointConnectionId(String id){ this.secureChannel.setEndpointConnectionId(id); } + + private void notifyHandshakeCompleteLock(){ + synchronized (idscpHandshakeLock){ + idscpHandshakeLock.notify(); + } + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index e797aa3cc..ccc0f88aa 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -2,4 +2,5 @@ public interface FsmListener { void onMessage(byte[] data); + void onControlMessage(InternalControlMessage controlMessage); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index beaa0a33a..946dd2bc5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -1,4 +1,15 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; public enum InternalControlMessage { + START_IDSCP_HANDSHAKE, + DAT_TIMER_EXPIRED, + RAT_VERIFIER_SUCCESSFUL, + RAT_VERIFIER_FAILED, + RAT_PROVER_SUCCESSFUL, + RAT_PROVER_FAILED, + DAT_VERIFICATION_SUCCESSFUL, + DAT_VERIFICATION_FAILED, + ERROR, + IDSCP_STOP, + SEND_IDSCP_MESSAGE } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 2c1385ae1..1d769f1fc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -1,4 +1,16 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import java.util.function.Function; + public class State { + + private Function eventHandler; + + public State feedEvent(Event e){ + return eventHandler.apply(e); + } + + public void setEventHandler(Function eventHandler) { + this.eventHandler = eventHandler; + } } From 3aa4edb3cd38e98440276eae6d2d85185db4b188 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 16 Jan 2020 16:29:39 +0100 Subject: [PATCH 040/237] WIP: FSM add transitions, add Rat dummy --- .../daps/DefaultDapsDriver.java | 2 +- .../default_driver_impl/rat/TPM2Prover.java | 50 ++ .../rat/TPM2ProverImpl.java | 9 + .../default_driver_impl/rat/TPM2Verifier.java | 50 ++ .../rat/TPM2VerifierImpl.java | 9 + .../idscp2/drivers/interfaces/DapsDriver.java | 1 - .../drivers/interfaces/RatProverDriver.java | 4 +- .../drivers/interfaces/RatProverInstance.java | 8 + .../drivers/interfaces/RatVerifierDriver.java | 3 + .../interfaces/RatVerifierInstance.java | 8 + .../configuration/IDSCPv2Settings.java | 2 +- .../finite_state_machine/Event.java | 14 +- .../idscp_core/finite_state_machine/FSM.java | 471 ++++++++++-------- .../InternalControlMessage.java | 29 +- .../finite_state_machine/State.java | 27 +- .../finite_state_machine/Transition.java | 20 + .../src/test/java/IDSCPv2ClientInitiator.java | 12 +- .../src/test/java/IDSCPv2ServerInitiator.java | 14 +- 18 files changed, 495 insertions(+), 238 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index e2e79bffe..dc0564a26 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -16,6 +16,6 @@ public byte[] getToken() { @Override public boolean verifyToken(byte[] dat) { - return false; + return true; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java new file mode 100644 index 000000000..7a9a0f896 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -0,0 +1,50 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverInstance; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; +import de.fhg.aisec.ids.messages.IDSCPv2.*; + +public class TPM2Prover extends Thread implements RatProverInstance{ + + private boolean running = true; + private FsmListener fsmListener; + private boolean successful = false; + private final Object resultAvailableLock = new Object(); + + + TPM2Prover(FsmListener fsmListener){ + this.fsmListener = fsmListener; + } + + @Override + public void delegate(IdscpMessage message) { + successful = true; + synchronized (resultAvailableLock) { + resultAvailableLock.notify(); + } + } + + public void terminate(){ + running = false; + } + + @Override + public void run() { + while (running){ + synchronized (resultAvailableLock) { + try { + resultAvailableLock.wait(); + if (successful){ + fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_SUCCESSFUL); + } else { + fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_FAILED); + } + running = false; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java index 63d8c51ba..4086b374a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java @@ -1,6 +1,8 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverInstance; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; /** * Remote Attestation Prover Driver implementation class for TPM2.0 @@ -8,4 +10,11 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class TPM2ProverImpl implements RatProverDriver { + + @Override + public RatProverInstance start(FsmListener fsmListener) { + TPM2Prover newProver = new TPM2Prover(fsmListener); + newProver.start(); + return newProver; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java new file mode 100644 index 000000000..46ff23105 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -0,0 +1,50 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierInstance; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; +import de.fhg.aisec.ids.messages.IDSCPv2; + +public class TPM2Verifier extends Thread implements RatVerifierInstance { + + private FsmListener fsmListener; + private boolean successful = false; + private boolean running = true; + private final Object resultAvailableLock = new Object(); + + TPM2Verifier(FsmListener fsmListener){ + this.fsmListener = fsmListener; + } + + @Override + public void delegate(IDSCPv2.IdscpMessage message) { + successful = true; + synchronized (resultAvailableLock) { + resultAvailableLock.notify(); + } + } + + @Override + public void terminate() { + running = false; + } + + @Override + public void run(){ + while (running){ + synchronized (resultAvailableLock) { + try { + resultAvailableLock.wait(); + if (successful){ + fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_SUCCESSFUL); + } else { + fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_FAILED); + } + running = false; + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java index c67acb75d..d92ca8f67 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java @@ -1,6 +1,8 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierInstance; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; /** * Remote Attestation Verifier Driver implementation class for TPM2.0 @@ -8,4 +10,11 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class TPM2VerifierImpl implements RatVerifierDriver { + + @Override + public RatVerifierInstance start(FsmListener fsmListener) { + TPM2Verifier newVerifier = new TPM2Verifier(fsmListener); + newVerifier.start(); + return newVerifier; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index ebc2c2c47..164fa485a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -6,7 +6,6 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface DapsDriver { - byte[] getToken(); boolean verifyToken(byte[] dat); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index eb410c0dc..0f4765b50 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -1,10 +1,12 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; + /** * An interface for the remote attestation prover driver that is used for proving the current state by RAT mechanism * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface RatProverDriver { - + RatProverInstance start(FsmListener fsmListener); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java new file mode 100644 index 000000000..32a8401bd --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java @@ -0,0 +1,8 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +import de.fhg.aisec.ids.messages.IDSCPv2; + +public interface RatProverInstance { + void delegate(IDSCPv2.IdscpMessage message); + void terminate(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index aabc88d10..a2a265b9b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -1,9 +1,12 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; + /** * An interface for the remote attestation verifier driver that is used for verifying provers system sate * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface RatVerifierDriver { + RatVerifierInstance start(FsmListener fsmListener); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java new file mode 100644 index 000000000..494631bff --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java @@ -0,0 +1,8 @@ +package de.fhg.aisec.ids.idscp2.drivers.interfaces; + +import de.fhg.aisec.ids.messages.IDSCPv2; + +public interface RatVerifierInstance { + void delegate(IDSCPv2.IdscpMessage message); + void terminate(); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index 8e943d931..749281acf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -6,7 +6,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class IDSCPv2Settings { - public static final int DEFAULT_SERVER_PORT = 8081; + public static final int DEFAULT_SERVER_PORT = 8080; private int serverPort = DEFAULT_SERVER_PORT; private String host = "localhost"; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index ce3e4a36d..62d99ff5a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -2,6 +2,12 @@ import de.fhg.aisec.ids.messages.IDSCPv2.*; +/** + * An Event class for the Finite State Machine. Triggers a transition and holds either an idscpMessage or an + * InternalControlMessage. + * + * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de + */ public class Event { public enum EventType { IDSCP_MESSAGE, @@ -13,15 +19,15 @@ public enum EventType { private IdscpMessage idscpMessage; private InternalControlMessage controlMessage; - public Event(Object key, InternalControlMessage controlMessage){ - this.key = key; + public Event(InternalControlMessage controlMessage){ + this.key = controlMessage.getValue(); this.type = EventType.INTERNAL_CONTROL_MESSAGE; this.controlMessage = controlMessage; this.idscpMessage = null; } - public Event (Object key, IdscpMessage idscpMessage){ - this.key = key; + public Event (IdscpMessage idscpMessage){ + this.key = idscpMessage.getMessageCase().getNumber(); this.type = EventType.IDSCP_MESSAGE; this.idscpMessage = idscpMessage; this.controlMessage = null; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 83bd9f3a5..beb427fcb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -1,15 +1,12 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import com.google.protobuf.InvalidProtocolBufferException; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2.*; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.Event.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +26,7 @@ public class FSM implements FsmListener{ private final State STATE_ESTABLISHED = new State(); /* ---------------- end of states --------------- */ + //toDo error codes private State currentState; private final State initialState = STATE_CLOSED; @@ -41,6 +39,12 @@ public class FSM implements FsmListener{ private IdscpMessage cachedIdscpHello = null; private final Object idscpHandshakeLock = new Object(); private final Object fsmIsBusy = new Object(); + //toDo cipher suites + private String[] ratSupportedSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; + private String[] ratExpectedSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; + private byte[] remoteDat = null; + private RatProverInstance ratProver = null; + private RatVerifierInstance ratVerifier = null; public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, DapsDriver dapsDriver){ @@ -53,217 +57,273 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr /* ----------- Protocol Transitions ---------- */ - STATE_CLOSED.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - * INTERNAL_CONTROL_MESSAGE.START_IDSCP_HANDSHAKE ---> send IDSCP_HELLO ---> STATE_WAIT_FOR_HELLO - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_MESSAGE.IDSCP_HELLO ---> cache IDSCP_HELLO ---> STATE_CLOSED - * ALL_OTHER_MESSAGES ---> STATE_CLOSED - */ - e -> { - LOG.debug("STATE_CLOSED triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - if (e.getControlMessage().equals(InternalControlMessage.START_IDSCP_HANDSHAKE)){ - LOG.debug("Get DAT Token vom DAT_DRIVER"); - //toDo this.dapsDriver.getToken(); - LOG.debug("Send idscp hello"); - IdscpMessage idscpHello = IdscpMessageFactory. - getIdscpHelloMessage(new byte[]{}, new String[] {"a", "b"}, new String[] {"a", "b"}); - this.send(idscpHello); - //toDo set handshake timeout - LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); - return STATE_WAIT_FOR_HELLO; - } - } else { /* IDSCP_MESSAGE */ - if (e.getIdscpMessage().hasIdscpHello()){ - LOG.debug("Cache idscp hello message"); - this.cachedIdscpHello = e.getIdscpMessage(); - } - } + /*--------------------------------------------------- + * STATE_CLOSED - Transition Description + * --------------------------------------------------- + * INTERNAL_CONTROL_MESSAGE.START_IDSCP_HANDSHAKE ---> send IDSCP_HELLO ---> STATE_WAIT_FOR_HELLO + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_MESSAGE.IDSCP_HELLO ---> cache IDSCP_HELLO ---> STATE_CLOSED + * ALL_OTHER_MESSAGES ---> STATE_CLOSED + * --------------------------------------------------- */ + STATE_CLOSED.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( + event -> { + LOG.debug("Get DAT Token vom DAT_DRIVER"); + byte[] dat = this.dapsDriver.getToken(); + LOG.debug("Send IDSCP_HELLO"); + IdscpMessage idscpHello = IdscpMessageFactory. + getIdscpHelloMessage(dat, this.ratSupportedSuite, this.ratExpectedSuite); + this.send(idscpHello); + //toDo set handshake timeout + LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); + return STATE_WAIT_FOR_HELLO; + } + )); + STATE_CLOSED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_CLOSE"); + IdscpMessage idscpClose = IdscpMessageFactory.getIdscpCloseMessage(); + send(idscpClose); LOG.debug("Stay in state STATE_CLOSED"); notifyHandshakeCompleteLock(); - return this.STATE_CLOSED; + return STATE_CLOSED; } - ); + )); - STATE_WAIT_FOR_HELLO.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send idscp close ---> STATE_CLOSED - * IDSCP_CLOSE ---> STATE_CLOSED - * toDo IDSCP_HELLO ---> DAT Verification failed: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_HELLO ---> verify DAT, set DAT Timeout, start RAT P&V ---> STATE_WAIT_FOR_RAT - * ALL_OTHER_MESSAGES ---> STATE_WAIT_FOR_HELLO - */ - e -> { - LOG.debug("STATE_WAIT_FOR_HELLO triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - if (e.getControlMessage().equals(InternalControlMessage.ERROR)){ - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage()); - notifyHandshakeCompleteLock(); - return STATE_CLOSED; - } - - if (e.getControlMessage().equals(InternalControlMessage.IDSCP_STOP)){ - LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage()); - notifyHandshakeCompleteLock(); - return STATE_CLOSED; - } - } else { //IDSCP_MESSAGE - if (e.getIdscpMessage().hasIdscpClose()){ - LOG.debug(""); - } else if (e.getIdscpMessage().hasIdscpHello()) { - LOG.debug("Verify received DAT"); - //toDo Dat verification - //toDo set DAT timeout - //toDo start RAT_PROVER - //toDo start RAT_VERIFIER - LOG.debug("Switch to state STATE_ESTABLISHED"); - notifyHandshakeCompleteLock(); - return STATE_ESTABLISHED; - } - } - LOG.debug("Stay in state STATE_WAIT_FOR_HELLO"); - return this.STATE_WAIT_FOR_HELLO; + STATE_CLOSED.addTransition(IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Cache IDSCP_HELLO"); + this.cachedIdscpHello = event.getIdscpMessage(); + LOG.debug("Stay in state STATE_CLOSED"); + return STATE_CLOSED; } - ); + )); - STATE_WAIT_FOR_RAT.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - */ - e -> { - LOG.debug("STATE_WAIT_FOR_RAT triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - - } else { //IDSCP_MESSAGE - - } - return this.STATE_WAIT_FOR_RAT; + STATE_CLOSED.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; } - ); - - STATE_WAIT_FOR_RAT_CLIENT.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - */ - e -> { - LOG.debug("STATE_WAIT_FOR_RAT_CLIENT triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ + ); + + /*--------------------------------------------------- + * STATE_WAIT_FOR_HELLO - Transition Description + * --------------------------------------------------- + * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.TIMEOUT ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_HELLO ---> RAT no match: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_HELLO ---> DAT Verification failed: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * IDSCP_HELLO ---> verify DAT, verifyRatCipher, set DAT Timeout, start RAT P&V ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> STATE_WAIT_FOR_HELLO + * --------------------------------------------------- */ + STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; + } + )); - } else { //IDSCP_MESSAGE + STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; + } + )); + STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_ERROR and IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpErrorMessage("Timeout", "")); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_HELLO"); + IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); + LOG.debug("Calculate Rat mechanisms"); + if (!calculateRatMechanisms(null, null) //toDo rat ciphers + ){ + LOG.debug("Cannot find a match for RAT cipher. Send IDSCP_ERROR and IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpErrorMessage("No match for RAT mechanism", "")); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; } - return this.STATE_WAIT_FOR_RAT_CLIENT; + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + if (!idscpHello.hasDynamicAttributeToken() || !this.dapsDriver + .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ + LOG.debug("No valid remote DAT is available. Send IDSCP_ERROR and IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpErrorMessage("No valid DAT", "")); + send(IdscpMessageFactory.getIdscpCloseMessage()); + notifyHandshakeCompleteLock(); + LOG.debug("Switch to state STATE_CLOSED"); + return STATE_CLOSED; + } + LOG.debug("Remote DAT is valid"); + //toDo set DAT timeout + LOG.debug("Start RAT Prover and Verifier"); + //toDo which RAT mechanism is chosen + this.ratVerifier = ratVerifierDriver.start(this); + this.ratProver = ratProverDriver.start(this); + LOG.debug("Switch to state STATE_ESTABLISHED"); + notifyHandshakeCompleteLock(); + return STATE_ESTABLISHED; } - ); - - STATE_WAIT_FOR_RAT_SERVER.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - */ - e -> { - LOG.debug("STATE_WAIT_FOR_RAT_SERVER triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - - } else { //IDSCP_MESSAGE + )); - } - return this.STATE_WAIT_FOR_RAT_SERVER; + STATE_WAIT_FOR_HELLO.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_HELLO"); + return STATE_WAIT_FOR_HELLO; } ); - STATE_WAIT_FOR_DAT_AND_RAT_CLIENT.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - */ - e -> { - LOG.debug("STATE_WAIT_FOR_DAT_AND_RAT_CLIENT triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - - } else { //IDSCP_MESSAGE + /*--------------------------------------------------- + * STATE_WAIT_FOR_RAT - Transition Description + * --------------------------------------------------- + * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.DAT_TIMER_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT + * //toDo INTERNAL_CONTROL_MESSAGE.SEND_IDSCP_MESSAGE ---> send IDSCP_DATA ---> STATE_ESTABLISHED + * INTERNAL_CONTROL_MESSAGE.REPEAT_RAT ---> send IDSCP_RE_RAT ---> WAIT_FOR_RAT_CLIENT + * IDSCP_MESSAGE.RE_RAT ---> start RAT_Prover ---> STATE_WAIT_FOR_RAT_SERVER + * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED + * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED + * IDSCP_MESSAGE.DAT_EXPIRED ---> send DAT, start RAT_PROVER ---> STATE_WAIT_FOR_RAT_SERVER + * --------------------------------------------------- */ + + /*--------------------------------------------------- + * STATE_ESTABLISHED - Transition Description + * --------------------------------------------------- + * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED + * INTERNAL_CONTROL_MESSAGE.DAT_TIMER_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT + * //toDo INTERNAL_CONTROL_MESSAGE.SEND_IDSCP_MESSAGE ---> send IDSCP_DATA ---> STATE_ESTABLISHED + * INTERNAL_CONTROL_MESSAGE.REPEAT_RAT ---> send IDSCP_RE_RAT ---> WAIT_FOR_RAT_CLIENT + * IDSCP_MESSAGE.RE_RAT ---> start RAT_Prover ---> STATE_WAIT_FOR_RAT_SERVER + * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED + * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED + * IDSCP_MESSAGE.DAT_EXPIRED ---> send DAT, start RAT_PROVER ---> STATE_WAIT_FOR_RAT_SERVER + * --------------------------------------------------- */ + STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("Error occurred, send IDSCP_ERROR and IDSCP_CLOSE and close idscp connection"); + send(IdscpMessageFactory.getIdscpErrorMessage("Error occurred", "")); + send(IdscpMessageFactory.getIdscpCloseMessage()); + return STATE_CLOSED; + } + )); - } + STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("Close idscp connection and send IDSCP_CLOSE"); + return STATE_CLOSED; + } + )); + + STATE_ESTABLISHED.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); + send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + //toDo set dat timeout + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); return STATE_WAIT_FOR_DAT_AND_RAT_CLIENT; } - ); - - STATE_WAIT_FOR_DAT_AND_RAT_SERVER.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - */ - e -> { - LOG.debug("STATE_WAIT_FOR_DAT_AND_RAT_SERVER triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - - } else { //IDSCP_MESSAGE + )); + + STATE_ESTABLISHED.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( + event -> { + LOG.debug("RAT timer expired. Send IDSCP_RE_RAT"); + send(IdscpMessageFactory.getIdscpReRatMessage("RAT expired")); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_CLIENT"); + return STATE_WAIT_FOR_RAT_CLIENT; + } + )); + + STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RERAT with cause {}", event.getIdscpMessage().getIdscpReRat().getCause()); + LOG.debug("Start RAT_PROVER"); + //toDo trigger RAT_PROVER + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); + return STATE_WAIT_FOR_RAT_SERVER; + } + )); + + STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("DAT expired. Send new DAT and repeat RAT"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + //toDo trigger RAT Prover + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); + return STATE_WAIT_FOR_RAT_SERVER; + } + )); + + STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( + event -> { + try { + this.listenerLatch.await(); + this.listener.onMessage(event.getIdscpMessage()); + LOG.debug("Idscp data was passed to connection listener"); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + LOG.debug("Stay in state STATE_ESTABLISHED"); + return STATE_ESTABLISHED; + } + )); + + STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Receive IDSCP_CLOSED"); + try { + this.listenerLatch.await(); + this.listener.onMessage(event.getIdscpMessage()); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); } - return STATE_WAIT_FOR_DAT_AND_RAT_SERVER; + LOG.debug("Switch to STATE_CLOSED"); + return STATE_CLOSED; } - ); + )); - STATE_ESTABLISHED.setEventHandler( - /*-------------------------------- - * Transition description - * -------------------------------- - * INTERNAL_CONTROL_MESSAGE.ERROR ---> send idscp error, send idscp close ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send idscp close ---> STATE_CLOSED - * toDo INTERNAL_CONTROL_MESSAGE.DAT_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT - * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED - * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED - */ - e -> { - LOG.debug("STATE_ESTABLISHED triggered"); - if (e.getType().equals(EventType.INTERNAL_CONTROL_MESSAGE)){ - if (e.getControlMessage().equals(InternalControlMessage.ERROR)){ - LOG.debug("Error occurred, send IDSCP_ERROR and IDSCP_CLOSE and close idscp connection"); - send(IdscpMessageFactory.getIdscpErrorMessage("Error occurred", "")); - send(IdscpMessageFactory.getIdscpCloseMessage()); - return STATE_CLOSED; - } else if (e.getControlMessage().equals(InternalControlMessage.IDSCP_STOP)){ - send(IdscpMessageFactory.getIdscpCloseMessage()); - LOG.debug("Close idscp connection and send IDSCP_CLOSE"); - return STATE_CLOSED; - } - } else { //IDSCP_MESSAGE - IdscpMessage message = e.getIdscpMessage(); - if (message.hasIdscpData()){ - try { - this.listenerLatch.await(); - this.listener.onMessage(message); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } else if (message.hasIdscpClose()){ - LOG.debug("Receive IDSCP_CLOSED"); - try { - this.listenerLatch.await(); - this.listener.onMessage(message); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - LOG.debug("Switch to STATE_CLOSED"); - return STATE_CLOSED; - } - } - LOG.debug("Stay in STATE_ESTABLISHED"); + STATE_ESTABLISHED.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_ESTABLISHED"); return STATE_ESTABLISHED; } ); - /* ---------------- end of transitions --------------- */ //set initial state @@ -275,20 +335,20 @@ public void onMessage(byte[] data){ //parse message and create new IDSCP Message Event, then pass it to current state and update new state try { IdscpMessage message = IdscpMessage.parseFrom(data); - Event e = new Event(null, message); + Event e = new Event(message); synchronized (fsmIsBusy){ currentState = currentState.feedEvent(e); } } catch (InvalidProtocolBufferException e) { LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); - sendError("Cannot parse raw data into IdscpMessage", ""); + //toDo sendError("Cannot parse raw data into IdscpMessage", ""); } } @Override public void onControlMessage(InternalControlMessage controlMessage) { //create Internal Control Message Event and pass it to current state and update new state - Event e = new Event(null, controlMessage); + Event e = new Event(controlMessage); synchronized (fsmIsBusy){ currentState = currentState.feedEvent(e); } @@ -307,9 +367,9 @@ public void startIdscpHandshake() throws IDSCPv2Exception { onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); //check if a idscpHello was already received and trigger next transition - if (cachedIdscpHello != null){ - Event e = new Event(null, cachedIdscpHello); - synchronized (fsmIsBusy){ + synchronized (fsmIsBusy){ + if (cachedIdscpHello != null){ + Event e = new Event(cachedIdscpHello); currentState = currentState.feedEvent(e); } } @@ -335,22 +395,6 @@ public void send(IdscpMessage msg){ secureChannel.send(msg.toByteArray()); } - public void sendError(String msg, String code){ - IdscpMessage idscpMessage = IdscpMessage.newBuilder() - .setType(IdscpMessage.Type.IDSCP_ERROR) - .setIdscpError( - IdscpError.newBuilder() - .setErrorMsg(msg) - .setErrorCode(code) - ).build(); - send(idscpMessage); - } - - private void reset(){ - this.currentState = initialState; - } - - public boolean isConnected(){ return currentState.equals(STATE_ESTABLISHED); } @@ -369,4 +413,9 @@ private void notifyHandshakeCompleteLock(){ idscpHandshakeLock.notify(); } } + + private boolean calculateRatMechanisms(String[] remoteExpectedSuite, String[] remoteSupportedSuite){ + return true; + //toDo implement logic + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index 946dd2bc5..7b2075f71 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -1,15 +1,22 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; public enum InternalControlMessage { - START_IDSCP_HANDSHAKE, - DAT_TIMER_EXPIRED, - RAT_VERIFIER_SUCCESSFUL, - RAT_VERIFIER_FAILED, - RAT_PROVER_SUCCESSFUL, - RAT_PROVER_FAILED, - DAT_VERIFICATION_SUCCESSFUL, - DAT_VERIFICATION_FAILED, - ERROR, - IDSCP_STOP, - SEND_IDSCP_MESSAGE + START_IDSCP_HANDSHAKE("ICM_START"), + IDSCP_STOP("ICM_STOP"), + DAT_TIMER_EXPIRED("ICM_DAT_TIMER_EXPIRED"), + REPEAT_RAT("ICM_REPEAT_RAT"), + RAT_VERIFIER_SUCCESSFUL("ICM_RAT_V_SUC"), + RAT_VERIFIER_FAILED("ICM_RAT_V_FAILED"), + RAT_PROVER_SUCCESSFUL("ICM_RAT_P_SUC"), + RAT_PROVER_FAILED("ICM_RAT_P_FAILED"), + DAT_VERIFICATION_SUCCESSFUL("IFM_DAT_SUC"), + DAT_VERIFICATION_FAILED("ICM_DAT_FAILED"), + ERROR("ICM_ERROR"), + TIMEOUT("ICM_TIMEOUT"), + SEND_IDSCP_MESSAGE("ICM_SEND"); + + //set unique values that are different from IdscpMessage.MessageCase ot identify event.key + private final String id; + InternalControlMessage(String id) {this.id = id;} + public String getValue() {return id;} } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 1d769f1fc..75f540537 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -1,16 +1,33 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +/** + * A State class for the Finite State Machine. A state holds all outgoing transitions and a noTransitionHandler for + * events, that do not trigger any outgoing available transition. Transitions are mapped with the event key + * + * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de + */ public class State { - private Function eventHandler; + private ConcurrentHashMap transitions = new ConcurrentHashMap<>(); + private Function noTransitionHandler = null; - public State feedEvent(Event e){ - return eventHandler.apply(e); + State feedEvent(Event e){ + Transition t = transitions.get(e.getKey()); + if (t != null){ + return t.doTransition(e); + } else { + return noTransitionHandler.apply(e); + } } - public void setEventHandler(Function eventHandler) { - this.eventHandler = eventHandler; + void addTransition(Object k, Transition t){ + transitions.put(k,t); + } + + void setNoTransitionHandler(Function noTransitionHandler) { + this.noTransitionHandler = noTransitionHandler; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java new file mode 100644 index 000000000..76ec12731 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java @@ -0,0 +1,20 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import java.util.function.Function; + +/** + * Transition class for State machine, provides a doTransition method, that returns the next state for a given event + * + * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de + */ +class Transition { + private Function eventHandler; + + Transition(Function eventHandler){ + this.eventHandler = eventHandler; + } + + State doTransition(Event e){ + return eventHandler.apply(e); + } +} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 13694a6d0..ec8787bcf 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -1,5 +1,11 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2ProverImpl; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2VerifierImpl; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; @@ -13,8 +19,12 @@ public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings settings){ SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + DapsDriver dapsDriver = new DefaultDapsDriver(); + RatVerifierDriver ratVerifier = new TPM2VerifierImpl(); + RatProverDriver ratProver = new TPM2ProverImpl(); + IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, - null, null, null, secureChannelDriver); + dapsDriver, ratVerifier, ratProver, secureChannelDriver); clientConfig.connect(settings); } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 94c726704..cfc6b2d64 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,5 +1,11 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2ProverImpl; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2VerifierImpl; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; @@ -16,8 +22,12 @@ public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + DapsDriver dapsDriver = new DefaultDapsDriver(); + RatVerifierDriver ratVerifier = new TPM2VerifierImpl(); + RatProverDriver ratProver = new TPM2ProverImpl(); + IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, - null,null,null,secureChannelDriver); + dapsDriver, ratVerifier, ratProver, secureChannelDriver); IDSCPv2Server idscPv2Server; try { idscPv2Server = idscpServerConfig.listen(serverSettings); @@ -27,7 +37,7 @@ public void init(IDSCPv2Settings serverSettings) { } //secureServer.safeStop(); try { - Thread.sleep(40000); //run server for 5 minutes + Thread.sleep(120000); //run server for 2 minutes } catch (Exception e){ return; } From 435505ef6c770c2cfc519933e2c65aaadd3c985a Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 20 Jan 2020 15:05:22 +0100 Subject: [PATCH 041/237] Change protobuf structure, add Timer for idscp timeouts --- ids-api/src/main/proto/idscpv2.proto | 44 ++--- .../idscp2/idscp_core/IDSCPv2Connection.java | 2 +- .../idscp_core/IdscpMessageFactory.java | 23 +-- .../idscp_core/finite_state_machine/FSM.java | 158 ++++++++++-------- .../InternalControlMessage.java | 4 +- .../finite_state_machine/Timer.java | 45 +++++ 6 files changed, 160 insertions(+), 116 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java diff --git a/ids-api/src/main/proto/idscpv2.proto b/ids-api/src/main/proto/idscpv2.proto index ecf82336d..c118c773b 100644 --- a/ids-api/src/main/proto/idscpv2.proto +++ b/ids-api/src/main/proto/idscpv2.proto @@ -2,34 +2,18 @@ syntax = "proto3"; option java_package = "de.fhg.aisec.ids.messages"; option java_outer_classname = "IDSCPv2"; -//IDSCP message frame, contains a type identifier of the following message and the message +//IDSCP message frame message IdscpMessage { - enum Type { - IDSCP_HELLO = 0; //open a connection by sending an IDSCP_HELLO - IDSCP_CLOSE = 1; //send an IDSCP_CLOSE, that triggers connection close - IDSCP_ERROR = 2; //send an error message - IDSCP_DAT_EXPIRED = 3; //request a ne dynamicAttributeToken - IDSCP_DAT = 4; //send dynamicAttributeToken - IDSCP_RE_RAT = 5; //request a new remote Attestation - IDSCP_RAT_PROVER = 6; //send - IDSCP_RAT_VERIFIER = 7; //send - IDSCP_DATA = 8; //send IDSCP Payload - } - - // Identifies which field is filled in. - Type type = 1; - // One of the following will be filled in. oneof message { - IdscpHello idscpHello = 2; - IdscpClose idscpClose = 3; - IdscpError idscpError = 4; - IdscpDatExpired idscpDatExpired = 5; - IdscpDat idscpDat = 6; - IdscpReRat idscpReRat = 7; - IdscpRatProver idscpRatProver = 8; - IdscpRatVerifier idscpRatVerifier = 9; - IdscpData idscpData = 10; + IdscpHello idscpHello = 1; + IdscpClose idscpClose = 2; + IdscpDatExpired idscpDatExpired = 3; + IdscpDat idscpDat = 4; + IdscpReRat idscpReRat = 5; + IdscpRatProver idscpRatProver = 6; + IdscpRatVerifier idscpRatVerifier = 7; + IdscpData idscpData = 8; } } @@ -42,12 +26,14 @@ message IdscpHello { } message IdscpClose { + string cause_msg = 1; + string cause_code = 2; } -message IdscpError { - string error_code = 1; - string error_msg = 2; -} +//message IdscpError { +// string error_code = 1; +// string error_msg = 2; +// message IdscpDatExpired { //request new dynamicAttributeToken } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index 69761bd38..d747deb80 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -36,7 +36,7 @@ public void close() { } public void send(IdscpMessage msg) { - LOG.debug("Send idscp message of type {}", msg.getType()); + LOG.debug("Send idscp message"); fsm.send(msg); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index d284cfd4f..4f740bc70 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -20,33 +20,23 @@ public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRa .build(); return IdscpMessage.newBuilder() - .setType(IdscpMessage.Type.IDSCP_HELLO) .setIdscpHello(idscpHello) .build(); } - public static IdscpMessage getIdscpCloseMessage(){ - return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_CLOSE) - .setIdscpClose(IdscpClose.newBuilder().build()) - .build(); - } - - public static IdscpMessage getIdscpErrorMessage(String msg, String code){ - IdscpError idscpError = IdscpError.newBuilder() - .setErrorMsg(msg) - .setErrorCode(code) + public static IdscpMessage getIdscpCloseMessage(String closeMsg, String closeCode){ + IdscpClose idscpClose = IdscpClose.newBuilder() + .setCauseMsg(closeMsg) + .setCauseCode(closeCode) .build(); return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_ERROR) - .setIdscpError(idscpError) + .setIdscpClose(idscpClose) .build(); } public static IdscpMessage getIdscpDatExpiredMessage(){ return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_DAT_EXPIRED) .setIdscpDatExpired(IdscpDatExpired.newBuilder().build()) .build(); } @@ -57,7 +47,6 @@ public static IdscpMessage getIdscpDatMessage(byte[] dat){ .build(); return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_DAT) .setIdscpDat(idscpDat) .build(); } @@ -68,7 +57,6 @@ public static IdscpMessage getIdscpReRatMessage(String cause){ .build(); return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_RE_RAT) .setIdscpReRat(idscpReRat) .build(); } @@ -79,7 +67,6 @@ public static IdscpMessage getIdscpDataMessage(byte[] data){ .build(); return IdscpMessage.newBuilder() - . setType(IdscpMessage.Type.IDSCP_DATA) .setIdscpData(idscpData) .build(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index beb427fcb..b5d185ffd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -9,7 +9,6 @@ import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.util.concurrent.CountDownLatch; public class FSM implements FsmListener{ @@ -19,15 +18,14 @@ public class FSM implements FsmListener{ private final State STATE_CLOSED = new State(); private final State STATE_WAIT_FOR_HELLO = new State(); private final State STATE_WAIT_FOR_RAT= new State(); - private final State STATE_WAIT_FOR_RAT_CLIENT = new State(); - private final State STATE_WAIT_FOR_RAT_SERVER = new State(); - private final State STATE_WAIT_FOR_DAT_AND_RAT_CLIENT = new State(); - private final State STATE_WAIT_FOR_DAT_AND_RAT_SERVER = new State(); + private final State STATE_WAIT_FOR_RAT_VERIFIER = new State(); + private final State STATE_WAIT_FOR_RAT_PROVER = new State(); + private final State STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER = new State(); + private final State STATE_WAIT_FOR_DAT_AND_RAT = new State(); private final State STATE_ESTABLISHED = new State(); /* ---------------- end of states --------------- */ - //toDo error codes - + //toDo error codes in protobuf private State currentState; private final State initialState = STATE_CLOSED; private SecureChannel secureChannel; @@ -36,7 +34,6 @@ public class FSM implements FsmListener{ private DapsDriver dapsDriver; private IdscpMsgListener listener = null; private final CountDownLatch listenerLatch = new CountDownLatch(1); - private IdscpMessage cachedIdscpHello = null; private final Object idscpHandshakeLock = new Object(); private final Object fsmIsBusy = new Object(); //toDo cipher suites @@ -45,6 +42,9 @@ public class FSM implements FsmListener{ private byte[] remoteDat = null; private RatProverInstance ratProver = null; private RatVerifierInstance ratVerifier = null; + private Timer datTimer; + private Timer ratTimer; + private Timer handshakeTimer; public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, DapsDriver dapsDriver){ @@ -55,14 +55,40 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr this.dapsDriver = dapsDriver; secureChannel.setFsm(this); + /* ------------- Timeout Handler Routines ------------*/ + Runnable handshakeTimeoutHandler = new Runnable() { + @Override + public void run() { + onControlMessage(InternalControlMessage.TIMEOUT); + } + }; + + Runnable datTimeoutHandler = new Runnable() { + @Override + public void run() { + onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); + } + }; + + Runnable ratTimeoutHandler = new Runnable() { + @Override + public void run() { + onControlMessage(InternalControlMessage.RAT_TIMER_EXPIRED); + } + }; + //toDo set correct delays + this.handshakeTimer = new Timer(handshakeTimeoutHandler); + this.datTimer = new Timer(datTimeoutHandler); + this.ratTimer = new Timer(ratTimeoutHandler); + /* ------------- end timeout routines ------------- */ + + /* ----------- Protocol Transitions ---------- */ /*--------------------------------------------------- * STATE_CLOSED - Transition Description * --------------------------------------------------- * INTERNAL_CONTROL_MESSAGE.START_IDSCP_HANDSHAKE ---> send IDSCP_HELLO ---> STATE_WAIT_FOR_HELLO - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_MESSAGE.IDSCP_HELLO ---> cache IDSCP_HELLO ---> STATE_CLOSED * ALL_OTHER_MESSAGES ---> STATE_CLOSED * --------------------------------------------------- */ STATE_CLOSED.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( @@ -73,32 +99,14 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr IdscpMessage idscpHello = IdscpMessageFactory. getIdscpHelloMessage(dat, this.ratSupportedSuite, this.ratExpectedSuite); this.send(idscpHello); - //toDo set handshake timeout + fsmIsBusy.notify(); //enables fsm.onMessage() + LOG.debug("Set handshake timeout to 3 seconds"); + handshakeTimer.resetTimeout(3); LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); return STATE_WAIT_FOR_HELLO; } )); - STATE_CLOSED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_CLOSE"); - IdscpMessage idscpClose = IdscpMessageFactory.getIdscpCloseMessage(); - send(idscpClose); - LOG.debug("Stay in state STATE_CLOSED"); - notifyHandshakeCompleteLock(); - return STATE_CLOSED; - } - )); - - STATE_CLOSED.addTransition(IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Cache IDSCP_HELLO"); - this.cachedIdscpHello = event.getIdscpMessage(); - LOG.debug("Stay in state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - STATE_CLOSED.setNoTransitionHandler( event -> { LOG.debug("No transition available for given event " + event.toString()); @@ -123,7 +131,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage()); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; @@ -133,7 +141,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage()); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; @@ -151,9 +159,8 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { - LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_ERROR and IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpErrorMessage("Timeout", "")); - send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", "")); notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; @@ -167,9 +174,8 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr LOG.debug("Calculate Rat mechanisms"); if (!calculateRatMechanisms(null, null) //toDo rat ciphers ){ - LOG.debug("Cannot find a match for RAT cipher. Send IDSCP_ERROR and IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpErrorMessage("No match for RAT mechanism", "")); - send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("Cannot find a match for RAT cipher. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT mechanism", "")); notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; @@ -178,9 +184,8 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr //check if Dat is available and verify dat if (!idscpHello.hasDynamicAttributeToken() || !this.dapsDriver .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ - LOG.debug("No valid remote DAT is available. Send IDSCP_ERROR and IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpErrorMessage("No valid DAT", "")); - send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", "")); notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; @@ -218,6 +223,19 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED * IDSCP_MESSAGE.DAT_EXPIRED ---> send DAT, start RAT_PROVER ---> STATE_WAIT_FOR_RAT_SERVER * --------------------------------------------------- */ + /*STATE_WAIT_FOR_RAT.addTransition(, new Transition( + event -> { + + } + ));*/ + + STATE_WAIT_FOR_RAT.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + ); /*--------------------------------------------------- * STATE_ESTABLISHED - Transition Description @@ -234,16 +252,15 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr * --------------------------------------------------- */ STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("Error occurred, send IDSCP_ERROR and IDSCP_CLOSE and close idscp connection"); - send(IdscpMessageFactory.getIdscpErrorMessage("Error occurred", "")); - send(IdscpMessageFactory.getIdscpCloseMessage()); + LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); return STATE_CLOSED; } )); STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - send(IdscpMessageFactory.getIdscpCloseMessage()); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); LOG.debug("Close idscp connection and send IDSCP_CLOSE"); return STATE_CLOSED; } @@ -255,7 +272,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr send(IdscpMessageFactory.getIdscpDatExpiredMessage()); //toDo set dat timeout LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); - return STATE_WAIT_FOR_DAT_AND_RAT_CLIENT; + return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } )); @@ -264,7 +281,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr LOG.debug("RAT timer expired. Send IDSCP_RE_RAT"); send(IdscpMessageFactory.getIdscpReRatMessage("RAT expired")); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_CLIENT"); - return STATE_WAIT_FOR_RAT_CLIENT; + return STATE_WAIT_FOR_RAT_VERIFIER; } )); @@ -274,7 +291,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr LOG.debug("Start RAT_PROVER"); //toDo trigger RAT_PROVER LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); - return STATE_WAIT_FOR_RAT_SERVER; + return STATE_WAIT_FOR_RAT_PROVER; } )); @@ -284,7 +301,7 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); //toDo trigger RAT Prover LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); - return STATE_WAIT_FOR_RAT_SERVER; + return STATE_WAIT_FOR_RAT_PROVER; } )); @@ -333,15 +350,25 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr @Override public void onMessage(byte[] data){ //parse message and create new IDSCP Message Event, then pass it to current state and update new state + IdscpMessage message; try { - IdscpMessage message = IdscpMessage.parseFrom(data); - Event e = new Event(message); - synchronized (fsmIsBusy){ - currentState = currentState.feedEvent(e); - } + message = IdscpMessage.parseFrom(data); } catch (InvalidProtocolBufferException e) { - LOG.warn("Cannot parse raw data into IdscpMessage {}. Send error message", data); - //toDo sendError("Cannot parse raw data into IdscpMessage", ""); + LOG.warn("Cannot parse raw data into IdscpMessage {}", data); + return; + } + + Event event = new Event(message); + //must wait when fsm is in state STATE_CLOSED --> wait() will be notified when fsm is leaving STATE_CLOSED + synchronized (fsmIsBusy){ + while (currentState == STATE_CLOSED){ + try { + fsmIsBusy.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + currentState = currentState.feedEvent(event); } } @@ -366,14 +393,6 @@ public void startIdscpHandshake() throws IDSCPv2Exception { //trigger handshake init onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); - //check if a idscpHello was already received and trigger next transition - synchronized (fsmIsBusy){ - if (cachedIdscpHello != null){ - Event e = new Event(cachedIdscpHello); - currentState = currentState.feedEvent(e); - } - } - try { //wait until handshake was successful or failed synchronized (idscpHandshakeLock) { @@ -392,7 +411,14 @@ public void startIdscpHandshake() throws IDSCPv2Exception { } public void send(IdscpMessage msg){ - secureChannel.send(msg.toByteArray()); + //send messages from user only when idscp connection is established + synchronized(fsmIsBusy){ + if(isConnected()){ + secureChannel.send(msg.toByteArray()); + } else { + LOG.error("Cannot send IDSCP_DATA because protocol is not established"); + } + } } public boolean isConnected(){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index 7b2075f71..4287f8bac 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -4,6 +4,7 @@ public enum InternalControlMessage { START_IDSCP_HANDSHAKE("ICM_START"), IDSCP_STOP("ICM_STOP"), DAT_TIMER_EXPIRED("ICM_DAT_TIMER_EXPIRED"), + RAT_TIMER_EXPIRED("ICM_RAT_TIMER_EXPIRED"), REPEAT_RAT("ICM_REPEAT_RAT"), RAT_VERIFIER_SUCCESSFUL("ICM_RAT_V_SUC"), RAT_VERIFIER_FAILED("ICM_RAT_V_FAILED"), @@ -12,8 +13,7 @@ public enum InternalControlMessage { DAT_VERIFICATION_SUCCESSFUL("IFM_DAT_SUC"), DAT_VERIFICATION_FAILED("ICM_DAT_FAILED"), ERROR("ICM_ERROR"), - TIMEOUT("ICM_TIMEOUT"), - SEND_IDSCP_MESSAGE("ICM_SEND"); + TIMEOUT("ICM_TIMEOUT"); //set unique values that are different from IdscpMessage.MessageCase ot identify event.key private final String id; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java new file mode 100644 index 000000000..cf420dd7a --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -0,0 +1,45 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import static java.util.concurrent.TimeUnit.*; + +public class Timer { + + private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); + private ScheduledFuture timer; + private boolean isLocked = false; + private boolean isExecuting = false; + private Runnable timeoutHandler; + + public Timer(Runnable timeoutHandler){ + this.timeoutHandler = timeoutHandler; + } + + public void cancelTimeout() { + if (!isLocked) { + if (isExecuting) { + timer.cancel(true); + } + } + } + + public boolean resetTimeout(int delay){ + if (!isLocked){ + if (isExecuting){ + timer.cancel(true); + } + timer = executor.schedule(timeoutHandler, delay, SECONDS); + return true; + } + return false; + } + + public void stop(){ + if (!isLocked){ + executor.shutdownNow(); + isLocked = true; + } + } + +} From 438a3bad8661974ce625b920f3142f1412554601 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 20 Jan 2020 17:58:18 +0100 Subject: [PATCH 042/237] WIP: Implementation of FSM, update ICMs --- .../default_driver_impl/rat/TPM2Prover.java | 7 +- .../default_driver_impl/rat/TPM2Verifier.java | 7 +- .../drivers/interfaces/RatProverInstance.java | 1 + .../interfaces/RatVerifierInstance.java | 1 + .../finite_state_machine/Event.java | 17 ++ .../idscp_core/finite_state_machine/FSM.java | 276 +++++++++++++----- .../InternalControlMessage.java | 8 +- 7 files changed, 244 insertions(+), 73 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java index 7a9a0f896..b05fa8778 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -29,6 +29,11 @@ public void terminate(){ running = false; } + @Override + public void restart() { + + } + @Override public void run() { while (running){ @@ -36,7 +41,7 @@ public void run() { try { resultAvailableLock.wait(); if (successful){ - fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_SUCCESSFUL); + fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_OK); } else { fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_FAILED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java index 46ff23105..45df0e390 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -29,6 +29,11 @@ public void terminate() { running = false; } + @Override + public void restart() { + + } + @Override public void run(){ while (running){ @@ -36,7 +41,7 @@ public void run(){ try { resultAvailableLock.wait(); if (successful){ - fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_SUCCESSFUL); + fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_OK); } else { fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_FAILED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java index 32a8401bd..29620b2df 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java @@ -5,4 +5,5 @@ public interface RatProverInstance { void delegate(IDSCPv2.IdscpMessage message); void terminate(); + void restart(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java index 494631bff..ddaff93ec 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java @@ -5,4 +5,5 @@ public interface RatVerifierInstance { void delegate(IDSCPv2.IdscpMessage message); void terminate(); + void restart(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index 62d99ff5a..f4c42d814 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -2,6 +2,8 @@ import de.fhg.aisec.ids.messages.IDSCPv2.*; +import javax.swing.*; + /** * An Event class for the Finite State Machine. Triggers a transition and holds either an idscpMessage or an * InternalControlMessage. @@ -33,6 +35,21 @@ public Event (IdscpMessage idscpMessage){ this.controlMessage = null; } + //for outgoing ratProver and ratVerifier messages + public Event (InternalControlMessage controlMessage, IdscpMessage idscpMessage){ + if (controlMessage.equals(InternalControlMessage.RAT_PROVER_MSG) || + controlMessage.equals(InternalControlMessage.RAT_VERIFIER_MSG)) + { + this.key = controlMessage.getValue(); + this.type = EventType.INTERNAL_CONTROL_MESSAGE; + this.idscpMessage = idscpMessage; + this.controlMessage = controlMessage; + } else { + throw new IllegalStateException("This constructor must only be by RAT_PROVER and " + + "RAT_VERIFIER for message passing"); + } + } + public Object getKey() { return key; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index b5d185ffd..765b81b93 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -88,7 +88,7 @@ public void run() { /*--------------------------------------------------- * STATE_CLOSED - Transition Description * --------------------------------------------------- - * INTERNAL_CONTROL_MESSAGE.START_IDSCP_HANDSHAKE ---> send IDSCP_HELLO ---> STATE_WAIT_FOR_HELLO + * onICM: start_handshake --> {send IDSCP_HELLO, set handshake_timeout} --> STATE_WAIT_FOR_HELLO * ALL_OTHER_MESSAGES ---> STATE_CLOSED * --------------------------------------------------- */ STATE_CLOSED.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( @@ -119,21 +119,22 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_HELLO - Transition Description * --------------------------------------------------- - * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.TIMEOUT ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_HELLO ---> RAT no match: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_HELLO ---> DAT Verification failed: send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * IDSCP_HELLO ---> verify DAT, verifyRatCipher, set DAT Timeout, start RAT P&V ---> STATE_WAIT_FOR_RAT - * ALL_OTHER_MESSAGES ---> STATE_WAIT_FOR_HELLO + * onICM: error --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: handshake_timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE---> {} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (no rat match) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (invalid DAT) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (SUCCESS) ---> {verify DAT, match RAT, set DAT Timeout, start RAT P&V, + * set handshake_timeout} ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_HELLO * --------------------------------------------------- */ STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); - notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); return STATE_CLOSED; } )); @@ -142,33 +143,34 @@ public void run() { event -> { LOG.debug("Send IDSC_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); - notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); return STATE_CLOSED; } )); - STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - notifyHandshakeCompleteLock(); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", "")); + LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); return STATE_CLOSED; } )); STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( event -> { + handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_HELLO"); IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); LOG.debug("Calculate Rat mechanisms"); @@ -176,8 +178,8 @@ public void run() { ){ LOG.debug("Cannot find a match for RAT cipher. Send IDSCP_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT mechanism", "")); - notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); return STATE_CLOSED; } LOG.debug("Verify received DAT"); @@ -186,11 +188,11 @@ public void run() { .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", "")); - notifyHandshakeCompleteLock(); LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); return STATE_CLOSED; } - LOG.debug("Remote DAT is valid"); + LOG.debug("Remote DAT is valid. Set dat timeout"); //toDo set DAT timeout LOG.debug("Start RAT Prover and Verifier"); //toDo which RAT mechanism is chosen @@ -198,7 +200,7 @@ public void run() { this.ratProver = ratProverDriver.start(this); LOG.debug("Switch to state STATE_ESTABLISHED"); notifyHandshakeCompleteLock(); - return STATE_ESTABLISHED; + return STATE_WAIT_FOR_RAT; } )); @@ -213,21 +215,164 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_RAT - Transition Description * --------------------------------------------------- - * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.DAT_TIMER_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT - * //toDo INTERNAL_CONTROL_MESSAGE.SEND_IDSCP_MESSAGE ---> send IDSCP_DATA ---> STATE_ESTABLISHED - * INTERNAL_CONTROL_MESSAGE.REPEAT_RAT ---> send IDSCP_RE_RAT ---> WAIT_FOR_RAT_CLIENT - * IDSCP_MESSAGE.RE_RAT ---> start RAT_Prover ---> STATE_WAIT_FOR_RAT_SERVER - * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED - * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED - * IDSCP_MESSAGE.DAT_EXPIRED ---> send DAT, start RAT_PROVER ---> STATE_WAIT_FOR_RAT_SERVER + * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_WAIT_FOR_RAT_PROVER + * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_verifier_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onICM: dat_timeout ---> {send DAT_EXPIRED, ratV.cancel()} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onICM: handshake_timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_RAT_PROVER ---> {delegate to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_DAT_EXPIRED ---> {send DAT, ratP.restart()} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> STATE_CLOSED + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT * --------------------------------------------------- */ - /*STATE_WAIT_FOR_RAT.addTransition(, new Transition( + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; } - ));*/ + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_VERIFIER OK"); + ratTimer.resetTimeout(3600); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", "")); + this.ratProver.terminate(); + this.ratVerifier.terminate(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_VERIFIER failed"); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", "")); + this.ratProver.terminate(); + this.ratVerifier.terminate(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + send(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_VERIFIER"); + send(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); + this.ratVerifier.terminate(); + send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", "")); + this.ratProver.terminate(); + this.ratVerifier.terminate(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_VERIFIER"); + this.ratVerifier.delegate(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_PROVER"); + this.ratProver.delegate(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + this.ratProver.restart(); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + this.ratVerifier.terminate(); + this.ratProver.terminate(); + handshakeTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); STATE_WAIT_FOR_RAT.setNoTransitionHandler( event -> { @@ -240,57 +385,60 @@ public void run() { /*--------------------------------------------------- * STATE_ESTABLISHED - Transition Description * --------------------------------------------------- - * INTERNAL_CONTROL_MESSAGE.ERROR ---> send IDSCP_ERROR, send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.IDSCP_STOP ---> send IDSCP_CLOSE ---> STATE_CLOSED - * INTERNAL_CONTROL_MESSAGE.DAT_TIMER_EXPIRED ---> send DAT_EXPIRED, set timeout ---> STATE_WAIT_FOR_DAT_AND_RAT_CLIENT - * //toDo INTERNAL_CONTROL_MESSAGE.SEND_IDSCP_MESSAGE ---> send IDSCP_DATA ---> STATE_ESTABLISHED - * INTERNAL_CONTROL_MESSAGE.REPEAT_RAT ---> send IDSCP_RE_RAT ---> WAIT_FOR_RAT_CLIENT - * IDSCP_MESSAGE.RE_RAT ---> start RAT_Prover ---> STATE_WAIT_FOR_RAT_SERVER - * IDSCP_MESSAGE.DATA ---> listener.onMessage() ---> STATE_ESTABLISHED - * IDSCP_MESSAGE.CLOSE ---> STATE_CLOSED - * IDSCP_MESSAGE.DAT_EXPIRED ---> send DAT, start RAT_PROVER ---> STATE_WAIT_FOR_RAT_SERVER + * onICM: error ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, set timeout} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onMessage: IDSCP_RERAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED + * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED * --------------------------------------------------- */ STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); + LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } )); STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { + LOG.debug("Send IDSCP_CLOSE"); send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); - LOG.debug("Close idscp connection and send IDSCP_CLOSE"); + LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } )); + STATE_ESTABLISHED.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( + event -> { + LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); + send(IdscpMessageFactory.getIdscpReRatMessage("")); + this.ratVerifier = this.ratVerifierDriver.start(this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + )); + STATE_ESTABLISHED.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( event -> { LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); send(IdscpMessageFactory.getIdscpDatExpiredMessage()); - //toDo set dat timeout + handshakeTimer.resetTimeout(10); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } )); - STATE_ESTABLISHED.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( - event -> { - LOG.debug("RAT timer expired. Send IDSCP_RE_RAT"); - send(IdscpMessageFactory.getIdscpReRatMessage("RAT expired")); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_CLIENT"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); - STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { - LOG.debug("Received IDSCP_RERAT with cause {}", event.getIdscpMessage().getIdscpReRat().getCause()); - LOG.debug("Start RAT_PROVER"); - //toDo trigger RAT_PROVER - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); + LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); + this.ratProver = this.ratProverDriver.start(this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } )); @@ -299,8 +447,8 @@ public void run() { event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - //toDo trigger RAT Prover - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_SERVER"); + this.ratProver = this.ratProverDriver.start(this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } )); @@ -323,12 +471,6 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Receive IDSCP_CLOSED"); - try { - this.listenerLatch.await(); - this.listener.onMessage(event.getIdscpMessage()); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } LOG.debug("Switch to STATE_CLOSED"); return STATE_CLOSED; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index 4287f8bac..bf6ce52ae 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -6,12 +6,12 @@ public enum InternalControlMessage { DAT_TIMER_EXPIRED("ICM_DAT_TIMER_EXPIRED"), RAT_TIMER_EXPIRED("ICM_RAT_TIMER_EXPIRED"), REPEAT_RAT("ICM_REPEAT_RAT"), - RAT_VERIFIER_SUCCESSFUL("ICM_RAT_V_SUC"), + RAT_VERIFIER_OK("ICM_RAT_V_OK"), RAT_VERIFIER_FAILED("ICM_RAT_V_FAILED"), - RAT_PROVER_SUCCESSFUL("ICM_RAT_P_SUC"), + RAT_PROVER_OK("ICM_RAT_P_OK"), RAT_PROVER_FAILED("ICM_RAT_P_FAILED"), - DAT_VERIFICATION_SUCCESSFUL("IFM_DAT_SUC"), - DAT_VERIFICATION_FAILED("ICM_DAT_FAILED"), + RAT_PROVER_MSG("ICM_RAT_PROVER_MSG"), + RAT_VERIFIER_MSG("ICM_RAT_VERIFIER_MSG"), ERROR("ICM_ERROR"), TIMEOUT("ICM_TIMEOUT"); From a579af9f9177f992a15cd8f7b42529844fe9e60d Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Wed, 22 Jan 2020 18:00:35 +0100 Subject: [PATCH 043/237] WIP: FSM, Add error codes to IDSCP_CLOSE in protobuf --- ids-api/src/main/proto/idscpv2.proto | 22 +- .../rat/TPM2ProverImpl.java | 2 +- .../rat/TPM2VerifierImpl.java | 2 +- .../drivers/interfaces/RatProverDriver.java | 2 +- .../drivers/interfaces/RatVerifierDriver.java | 2 +- .../idscp_core/IdscpMessageFactory.java | 4 +- .../idscp_core/finite_state_machine/FSM.java | 706 ++++++++++++++++-- 7 files changed, 680 insertions(+), 60 deletions(-) diff --git a/ids-api/src/main/proto/idscpv2.proto b/ids-api/src/main/proto/idscpv2.proto index c118c773b..88fab12cf 100644 --- a/ids-api/src/main/proto/idscpv2.proto +++ b/ids-api/src/main/proto/idscpv2.proto @@ -17,6 +17,7 @@ message IdscpMessage { } } + //IDSCP messages message IdscpHello { int32 version = 1; //IDSCP protocol version @@ -26,14 +27,21 @@ message IdscpHello { } message IdscpClose { - string cause_msg = 1; - string cause_code = 2; -} -//message IdscpError { -// string error_code = 1; -// string error_msg = 2; -// + enum CloseCause { + USER_SHUTDOWN = 0; + TIMEOUT = 1; + ERROR = 2; + NO_VALID_DAT = 3; + NO_RAT_MECHANISM_MATCH_PROVER = 4; + NO_RAT_MECHANISM_MATCH_VERIFIER = 5; + RAT_PROVER_FAILED = 6; + RAT_VERIFIER_FAILED = 7; + } + + CloseCause cause_code = 1; + string cause_msg = 2; +} message IdscpDatExpired { //request new dynamicAttributeToken } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java index 4086b374a..0a43fbd63 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java @@ -12,7 +12,7 @@ public class TPM2ProverImpl implements RatProverDriver { @Override - public RatProverInstance start(FsmListener fsmListener) { + public RatProverInstance start(String instance, FsmListener fsmListener) { TPM2Prover newProver = new TPM2Prover(fsmListener); newProver.start(); return newProver; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java index d92ca8f67..24ad65818 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java @@ -12,7 +12,7 @@ public class TPM2VerifierImpl implements RatVerifierDriver { @Override - public RatVerifierInstance start(FsmListener fsmListener) { + public RatVerifierInstance start(String instance, FsmListener fsmListener) { TPM2Verifier newVerifier = new TPM2Verifier(fsmListener); newVerifier.start(); return newVerifier; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index 0f4765b50..97cb5da6f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -8,5 +8,5 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface RatProverDriver { - RatProverInstance start(FsmListener fsmListener); + RatProverInstance start(String instance, FsmListener fsmListener); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index a2a265b9b..55730afc9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -8,5 +8,5 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface RatVerifierDriver { - RatVerifierInstance start(FsmListener fsmListener); + RatVerifierInstance start(String instance, FsmListener fsmListener); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index 4f740bc70..04982458f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -24,10 +24,10 @@ public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRa .build(); } - public static IdscpMessage getIdscpCloseMessage(String closeMsg, String closeCode){ + public static IdscpMessage getIdscpCloseMessage(String closeMsg, IdscpClose.CloseCause causeCode){ IdscpClose idscpClose = IdscpClose.newBuilder() + .setCauseCode(causeCode) .setCauseMsg(closeMsg) - .setCauseCode(closeCode) .build(); return IdscpMessage.newBuilder() diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 765b81b93..b3228fd23 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -37,14 +37,16 @@ public class FSM implements FsmListener{ private final Object idscpHandshakeLock = new Object(); private final Object fsmIsBusy = new Object(); //toDo cipher suites - private String[] ratSupportedSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; - private String[] ratExpectedSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; + private String[] localSupportedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; + private String[] localExpectedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; private byte[] remoteDat = null; private RatProverInstance ratProver = null; private RatVerifierInstance ratVerifier = null; private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; + private String proverMechanism = null; + private String verifierMechanism = null; public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, DapsDriver dapsDriver){ @@ -97,7 +99,7 @@ public void run() { byte[] dat = this.dapsDriver.getToken(); LOG.debug("Send IDSCP_HELLO"); IdscpMessage idscpHello = IdscpMessageFactory. - getIdscpHelloMessage(dat, this.ratSupportedSuite, this.ratExpectedSuite); + getIdscpHelloMessage(dat, this.localSupportedRatSuite, this.localExpectedRatSuite); this.send(idscpHello); fsmIsBusy.notify(); //enables fsm.onMessage() LOG.debug("Set handshake timeout to 3 seconds"); @@ -121,7 +123,7 @@ public void run() { * --------------------------------------------------- * onICM: error --> {send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: stop --> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: handshake_timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED * onMessage: IDSCP_CLOSE---> {} ---> STATE_CLOSED * onMessage: IDSCP_HELLO (no rat match) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED * onMessage: IDSCP_HELLO (invalid DAT) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED @@ -132,7 +134,7 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -142,7 +144,7 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -152,7 +154,7 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", "")); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -173,31 +175,50 @@ public void run() { handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_HELLO"); IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); + LOG.debug("Calculate Rat mechanisms"); - if (!calculateRatMechanisms(null, null) //toDo rat ciphers - ){ - LOG.debug("Cannot find a match for RAT cipher. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT mechanism", "")); + this.proverMechanism = getRatProverMechanism(this.localSupportedRatSuite, + (String [])idscpHello.getExpectedRatSuiteList().toArray()); + if (proverMechanism == null){ + LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", + IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; } + + this.verifierMechanism = getRatVerifierMechanism(localExpectedRatSuite, + (String [])idscpHello.getSupportedRatSuiteList().toArray()); + if (verifierMechanism == null){ + LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", + IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + LOG.debug("Verify received DAT"); //check if Dat is available and verify dat + byte[] dat; if (!idscpHello.hasDynamicAttributeToken() || !this.dapsDriver - .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ + .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", "")); + send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; } + this.remoteDat = dat; LOG.debug("Remote DAT is valid. Set dat timeout"); //toDo set DAT timeout + datTimer.resetTimeout(3600); + LOG.debug("Start RAT Prover and Verifier"); - //toDo which RAT mechanism is chosen - this.ratVerifier = ratVerifierDriver.start(this); - this.ratProver = ratProverDriver.start(this); + this.ratVerifier = ratVerifierDriver.start(verifierMechanism, this); + this.ratProver = ratProverDriver.start(proverMechanism, this); + LOG.debug("Switch to state STATE_ESTABLISHED"); notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_RAT; @@ -215,12 +236,12 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_RAT - Transition Description * --------------------------------------------------- - * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED + * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_WAIT_FOR_RAT_PROVER - * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: rat_verifier_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_failed ---> {ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_verifier_failed ---> {ratP.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT * onICM: dat_timeout ---> {send DAT_EXPIRED, ratV.cancel()} ---> STATE_WAIT_FOR_DAT_AND_RAT @@ -228,13 +249,17 @@ public void run() { * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT * onMessage: IDSCP_RAT_PROVER ---> {delegate to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT * onMessage: IDSCP_DAT_EXPIRED ---> {send DAT, ratP.restart()} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_CLOSE ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT * --------------------------------------------------- */ STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); + this.ratProver.terminate(); + this.ratVerifier.terminate(); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -243,8 +268,12 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { + this.ratProver.terminate(); + this.ratVerifier.terminate(); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -272,9 +301,10 @@ public void run() { event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", "")); - this.ratProver.terminate(); this.ratVerifier.terminate(); + this.datTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -284,10 +314,11 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_VERIFIER failed"); - LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", "")); this.ratProver.terminate(); - this.ratVerifier.terminate(); + this.datTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -325,9 +356,10 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", "")); this.ratProver.terminate(); this.ratVerifier.terminate(); + this.datTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -336,8 +368,8 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { - LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_VERIFIER"); - this.ratVerifier.delegate(event.getIdscpMessage()); + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + this.ratProver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -345,8 +377,8 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { - LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_PROVER"); - this.ratProver.delegate(event.getIdscpMessage()); + LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); + this.ratVerifier.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -367,7 +399,8 @@ public void run() { LOG.debug("Received IDSCP_CLOSE"); this.ratVerifier.terminate(); this.ratProver.terminate(); - handshakeTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -383,23 +416,592 @@ public void run() { ); /*--------------------------------------------------- - * STATE_ESTABLISHED - Transition Description + * STATE_WAIT_FOR_RAT_VERIFIER - Transition Description + * --------------------------------------------------- + * onICM: error ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: close ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, cancel ratV} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_ESTABLISHED + * onICM: rat_verifier_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {stop RAT_VERIFIER} ---> STATE_CLOSED + * onMessage: IDSCP_RAT_PROVER ---> {delegat to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onMessage: IDSCP_RE_RAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER + * --------------------------------------------------- */ + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + this.ratVerifier.terminate(); + this.datTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + this.datTimer.cancelTimeout(); + this.ratVerifier.terminate(); + this.handshakeTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + this.ratVerifier.terminate(); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); + this.ratVerifier.terminate(); + send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); + notifyHandshakeCompleteLock(); + return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_VERIFIER OK"); + //toDo set rat timeout + this.ratTimer.resetTimeout(3600); + LOG.debug("Switch to state STATE_ESTABLISHED"); + notifyHandshakeCompleteLock(); + return STATE_ESTABLISHED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_VERIFIER failed"); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_VERIFIER"); + send(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + this.ratVerifier.terminate(); + this.datTimer.stop(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); + this.ratVerifier.delegate(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT_VERIFIER.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + ); + + /*--------------------------------------------------- + * STATE_WAIT_FOR_RAT_PROVER - Transition Description + * --------------------------------------------------- + * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER, timeouts.terminate()} ---> STATE_CLOSED + * onICM: error ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onICM: rat_prover_ok ---> {} ---> STATE_ESTABLISHED + * onICM: rat_prover_failed ---> {send IDSCP_CLOSE, terminate ratP, cancel timeouts} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onICM: repeat_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_PROVER + * --------------------------------------------------- */ + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + this.ratProver.terminate(); + this.ratTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + this.ratProver.terminate(); + this.ratTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + this.handshakeTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + this.ratProver.terminate(); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); + notifyHandshakeCompleteLock(); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_ESTABLISHED"); + notifyHandshakeCompleteLock(); + return STATE_ESTABLISHED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + this.ratProver.terminate(); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + send(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( + event -> { + LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); + send(IdscpMessageFactory.getIdscpReRatMessage("")); + this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + this.ratProver.terminate(); + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + this.ratProver.restart(); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + this.ratProver.delegate(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); + this.ratProver.restart(); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + )); + + STATE_WAIT_FOR_RAT_PROVER.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return STATE_WAIT_FOR_RAT_PROVER; + } + ); + + /*--------------------------------------------------- + * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description * --------------------------------------------------- - * onICM: error ---> {send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: stop ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: error ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * onMessage: IDSCP_DAT(success) --> {verify DAT, set det_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFEIER + * onMessage: IDSCP_DAT(failed) --> {verify DAT, send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RE_RAT ---> {start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * --------------------------------------------------- */ + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + this.handshakeTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); + if (!this.dapsDriver.verifyToken(dat)){ + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + this.remoteDat = dat; + LOG.debug("Remote DAT is valid. Set dat timeout"); + //toDo set DAT timeout + datTimer.resetTimeout(3600); + //start RAT Verifier + this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); + return STATE_WAIT_FOR_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); + return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; + } + ); + + /*--------------------------------------------------- + * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description + * --------------------------------------------------- + * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: error ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_CLOSE ---> {ratP.stop(), timeouts.stop()} ---> STATE_CLOSED + * onMessage: IDSCP_DAT(success) ---> {verify dat, start dat_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_DAT(failed) ---> {verify dat, send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED + * --------------------------------------------------- */ + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + this.ratProver.terminate(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred, send IDSC_CLOSE"); + this.ratProver.terminate(); + this.handshakeTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + this.ratProver.terminate(); + send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); + return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Send IDSC_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + send(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + this.ratProver.terminate(); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); + if (!this.dapsDriver.verifyToken(dat)){ + this.ratProver.terminate(); + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); + LOG.debug("Switch to state STATE_CLOSED"); + notifyHandshakeCompleteLock(); + return STATE_CLOSED; + } + this.remoteDat = dat; + LOG.debug("Remote DAT is valid. Set dat timeout"); + //toDo set DAT timeout + datTimer.resetTimeout(3600); + //start RAT Verifier + this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); + return STATE_WAIT_FOR_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + this.ratProver.restart(); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + this.ratProver.delegate(event.getIdscpMessage()); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); + this.ratProver.restart(); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + )); + + STATE_WAIT_FOR_DAT_AND_RAT.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); + return STATE_WAIT_FOR_DAT_AND_RAT; + } + ); + + /*--------------------------------------------------- + * STATE_ESTABLISHED - Transition Description + * --------------------------------------------------- + * onICM: error ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED - * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, set timeout} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED * onMessage: IDSCP_RERAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED - * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE ---> {timeouts.cancel()} ---> STATE_CLOSED * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED * --------------------------------------------------- */ STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", "")); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } @@ -408,7 +1010,9 @@ public void run() { STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", "")); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } @@ -418,7 +1022,7 @@ public void run() { event -> { LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); send(IdscpMessageFactory.getIdscpReRatMessage("")); - this.ratVerifier = this.ratVerifierDriver.start(this); + this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); return STATE_WAIT_FOR_RAT_VERIFIER; } @@ -428,7 +1032,6 @@ public void run() { event -> { LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); send(IdscpMessageFactory.getIdscpDatExpiredMessage()); - handshakeTimer.resetTimeout(10); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } @@ -437,7 +1040,7 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); - this.ratProver = this.ratProverDriver.start(this); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -447,7 +1050,7 @@ public void run() { event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver = this.ratProverDriver.start(this); + this.ratProver = this.ratProverDriver.start(proverMechanism, this); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -471,6 +1074,8 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Receive IDSCP_CLOSED"); + datTimer.cancelTimeout(); + ratTimer.cancelTimeout(); LOG.debug("Switch to STATE_CLOSED"); return STATE_CLOSED; } @@ -582,8 +1187,15 @@ private void notifyHandshakeCompleteLock(){ } } - private boolean calculateRatMechanisms(String[] remoteExpectedSuite, String[] remoteSupportedSuite){ - return true; + //calculate Prover mechanism (strongest remote expected), returns null if no match was found + private String getRatProverMechanism(String[] localSupportedProver, String[] remoteExpectedVerifier){ + //toDo implement logic + return ""; + } + + //calculate Verifier mechanism (strongest local expected), returns null if no match was found + private String getRatVerifierMechanism(String[] localExpectedVerifier, String[] remoteSupportedProver){ //toDo implement logic + return ""; } } From c82ee29bf9b8b39e1143d9e7b12f0100020e7723 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 23 Jan 2020 18:04:11 +0100 Subject: [PATCH 044/237] WIP: FSM, new RAT Structure, timers, threads safe rat --- .../daps/DefaultDapsDriver.java | 6 +- .../default_driver_impl/rat/TPM2Prover.java | 37 +- .../rat/TPM2ProverImpl.java | 20 - .../default_driver_impl/rat/TPM2Verifier.java | 36 +- .../rat/TPM2VerifierImpl.java | 20 - .../idscp2/drivers/interfaces/DapsDriver.java | 2 +- .../drivers/interfaces/RatProverDriver.java | 24 +- .../drivers/interfaces/RatProverInstance.java | 9 - .../drivers/interfaces/RatVerifierDriver.java | 24 +- .../interfaces/RatVerifierInstance.java | 9 - .../idscp2/idscp_core/IDSCPv2Connection.java | 2 - .../idscp_core/IdscpMessageFactory.java | 16 + .../configuration/IDSCPv2Configuration.java | 11 +- .../idscp_core/finite_state_machine/FSM.java | 407 ++++++++++++------ .../finite_state_machine/FsmListener.java | 4 + .../rat_registry/RatProverDriverRegistry.java | 46 ++ .../RatVerifierDriverRegistry.java | 46 ++ .../src/test/java/IDSCPv2ClientInitiator.java | 15 +- .../src/test/java/IDSCPv2ServerInitiator.java | 16 +- 19 files changed, 467 insertions(+), 283 deletions(-) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index dc0564a26..35c229631 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -15,7 +15,7 @@ public byte[] getToken() { } @Override - public boolean verifyToken(byte[] dat) { - return true; - } + public int verifyToken(byte[] dat) { + return 3600; + } //returns number of seconds until dat is valid } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java index b05fa8778..706fd91fd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -1,54 +1,43 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverInstance; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2.*; -public class TPM2Prover extends Thread implements RatProverInstance{ +public class TPM2Prover extends RatProverDriver { - private boolean running = true; - private FsmListener fsmListener; - private boolean successful = false; - private final Object resultAvailableLock = new Object(); - - - TPM2Prover(FsmListener fsmListener){ - this.fsmListener = fsmListener; + public TPM2Prover(){ + super(); } @Override public void delegate(IdscpMessage message) { + //toDo blocking successful = true; synchronized (resultAvailableLock) { resultAvailableLock.notify(); } } - public void terminate(){ - running = false; - } - - @Override - public void restart() { - - } - @Override public void run() { + /*fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, + IdscpMessageFactory.getIdscpRatProverMessage());*/ while (running){ synchronized (resultAvailableLock) { - try { + /*try { resultAvailableLock.wait(); if (successful){ - fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_OK); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); } else { - fsmListener.onControlMessage(InternalControlMessage.RAT_PROVER_FAILED); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); } running = false; } catch (InterruptedException e) { e.printStackTrace(); - } + }*/ + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java deleted file mode 100644 index 0a43fbd63..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2ProverImpl.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; - -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverInstance; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; - -/** - * Remote Attestation Prover Driver implementation class for TPM2.0 - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class TPM2ProverImpl implements RatProverDriver { - - @Override - public RatProverInstance start(String instance, FsmListener fsmListener) { - TPM2Prover newProver = new TPM2Prover(fsmListener); - newProver.start(); - return newProver; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java index 45df0e390..d6a326846 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -1,54 +1,44 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierInstance; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2; -public class TPM2Verifier extends Thread implements RatVerifierInstance { +public class TPM2Verifier extends RatVerifierDriver { - private FsmListener fsmListener; - private boolean successful = false; - private boolean running = true; - private final Object resultAvailableLock = new Object(); - - TPM2Verifier(FsmListener fsmListener){ - this.fsmListener = fsmListener; + public TPM2Verifier(){ + super(); } @Override public void delegate(IDSCPv2.IdscpMessage message) { + //toDo blocking + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, + IdscpMessageFactory.getIdscpRatVerifierMessage()); successful = true; synchronized (resultAvailableLock) { resultAvailableLock.notify(); } } - @Override - public void terminate() { - running = false; - } - - @Override - public void restart() { - - } - @Override public void run(){ while (running){ synchronized (resultAvailableLock) { - try { + /*try { resultAvailableLock.wait(); if (successful){ - fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_OK); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); } else { - fsmListener.onControlMessage(InternalControlMessage.RAT_VERIFIER_FAILED); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); } running = false; } catch (InterruptedException e) { e.printStackTrace(); - } + }*/ + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java deleted file mode 100644 index 24ad65818..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2VerifierImpl.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; - -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierInstance; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; - -/** - * Remote Attestation Verifier Driver implementation class for TPM2.0 - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class TPM2VerifierImpl implements RatVerifierDriver { - - @Override - public RatVerifierInstance start(String instance, FsmListener fsmListener) { - TPM2Verifier newVerifier = new TPM2Verifier(fsmListener); - newVerifier.start(); - return newVerifier; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index 164fa485a..5314c1a35 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -7,5 +7,5 @@ */ public interface DapsDriver { byte[] getToken(); - boolean verifyToken(byte[] dat); + int verifyToken(byte[] dat); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index 97cb5da6f..7a2cefbae 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -1,12 +1,22 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import de.fhg.aisec.ids.messages.IDSCPv2; -/** - * An interface for the remote attestation prover driver that is used for proving the current state by RAT mechanism - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public interface RatProverDriver { - RatProverInstance start(String instance, FsmListener fsmListener); +public abstract class RatProverDriver extends Thread{ + + protected boolean running = true; + protected FsmListener fsmListener; + protected boolean successful = false; + protected final Object resultAvailableLock = new Object(); + + public void delegate(IDSCPv2.IdscpMessage message){} + + public void terminate() { + running = false; + } + + public void setListener(FsmListener listener){ + fsmListener = listener; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java deleted file mode 100644 index 29620b2df..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverInstance.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.interfaces; - -import de.fhg.aisec.ids.messages.IDSCPv2; - -public interface RatProverInstance { - void delegate(IDSCPv2.IdscpMessage message); - void terminate(); - void restart(); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 55730afc9..73112e1b2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -1,12 +1,22 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import de.fhg.aisec.ids.messages.IDSCPv2; -/** - * An interface for the remote attestation verifier driver that is used for verifying provers system sate - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public interface RatVerifierDriver { - RatVerifierInstance start(String instance, FsmListener fsmListener); +public abstract class RatVerifierDriver extends Thread{ + + protected boolean running = true; + protected FsmListener fsmListener; + protected boolean successful = false; + protected final Object resultAvailableLock = new Object(); + + public void delegate(IDSCPv2.IdscpMessage message){} + + public void terminate() { + running = false; + } + + public void setListener(FsmListener listener){ + fsmListener = listener; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java deleted file mode 100644 index ddaff93ec..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierInstance.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.interfaces; - -import de.fhg.aisec.ids.messages.IDSCPv2; - -public interface RatVerifierInstance { - void delegate(IDSCPv2.IdscpMessage message); - void terminate(); - void restart(); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index d747deb80..f67eed373 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -1,8 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpClose; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index 04982458f..3b917571a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -71,4 +71,20 @@ public static IdscpMessage getIdscpDataMessage(byte[] data){ .build(); } + public static IdscpMessage getIdscpRatProverMessage(){ + IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder().build(); + + return IdscpMessage.newBuilder() + .setIdscpRatProver(idscpRatProver) + .build(); + } + + public static IdscpMessage getIdscpRatVerifierMessage(){ + IdscpRatVerifier idscpRatVerifier = IdscpRatVerifier.newBuilder().build(); + + return IdscpMessage.newBuilder() + .setIdscpRatVerifier(idscpRatVerifier) + .build(); + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index af08a409d..26d17fd45 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -8,7 +8,6 @@ import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,20 +30,14 @@ public class IDSCPv2Configuration implements IDSCPv2Callback { private IDSCPv2Initiator user; private DapsDriver dapsDriver; - private RatProverDriver ratProverDriver; - private RatVerifierDriver ratVerifierDriver; private SecureChannelDriver secureChannelDriver; public IDSCPv2Configuration(IDSCPv2Initiator initiator, DapsDriver dapsDriver, - RatVerifierDriver ratVerifierDriver, - RatProverDriver ratProverDriver, SecureChannelDriver secureChannelDriver){ this.user = initiator; this.dapsDriver = dapsDriver; - this.ratVerifierDriver = ratVerifierDriver; - this.ratProverDriver = ratProverDriver; this.secureChannelDriver = secureChannelDriver; } @@ -74,7 +67,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, ratProverDriver, ratVerifierDriver, dapsDriver); + FSM fsm = new FSM(secureChannel, dapsDriver); String connectionId = UUID.randomUUID().toString(); //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock fsm.setEndpointConnectionId(connectionId); @@ -96,7 +89,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, ratProverDriver, ratVerifierDriver, dapsDriver); + FSM fsm = new FSM(secureChannel, dapsDriver); String connectionId = UUID.randomUUID().toString(); //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock fsm.setEndpointConnectionId(connectionId); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index b3228fd23..fb516c219 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -5,10 +5,13 @@ import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.util.concurrent.CountDownLatch; public class FSM implements FsmListener{ @@ -23,37 +26,39 @@ public class FSM implements FsmListener{ private final State STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER = new State(); private final State STATE_WAIT_FOR_DAT_AND_RAT = new State(); private final State STATE_ESTABLISHED = new State(); - /* ---------------- end of states --------------- */ - //toDo error codes in protobuf private State currentState; private final State initialState = STATE_CLOSED; + /* ---------------- end of states --------------- */ + private SecureChannel secureChannel; + private DapsDriver dapsDriver; + private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; - private DapsDriver dapsDriver; + private String currentRatProverId; //avoid messages from old provers + private String currentRatVerifierId; //avoid messages from old verifiers + private String proverMechanism = null; + private String verifierMechanism = null; + private IdscpMsgListener listener = null; private final CountDownLatch listenerLatch = new CountDownLatch(1); private final Object idscpHandshakeLock = new Object(); private final Object fsmIsBusy = new Object(); + //toDo cipher suites private String[] localSupportedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; private String[] localExpectedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; private byte[] remoteDat = null; - private RatProverInstance ratProver = null; - private RatVerifierInstance ratVerifier = null; + private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private String proverMechanism = null; - private String verifierMechanism = null; + private int ratTimeoutDelay = 3600; - public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDriver ratVerifier, - DapsDriver dapsDriver){ + public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ this.secureChannel = secureChannel; - this.ratProverDriver = ratProver; - this.ratVerifierDriver = ratVerifier; this.dapsDriver = dapsDriver; secureChannel.setFsm(this); @@ -61,21 +66,24 @@ public FSM(SecureChannel secureChannel, RatProverDriver ratProver, RatVerifierDr Runnable handshakeTimeoutHandler = new Runnable() { @Override public void run() { - onControlMessage(InternalControlMessage.TIMEOUT); + //onControlMessage(InternalControlMessage.TIMEOUT); + System.out.println("Handshake timeout"); } }; Runnable datTimeoutHandler = new Runnable() { @Override public void run() { - onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); + //onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); + System.out.println("DAT_TIMER_EXPIRED"); } }; Runnable ratTimeoutHandler = new Runnable() { @Override public void run() { - onControlMessage(InternalControlMessage.RAT_TIMER_EXPIRED); + //onControlMessage(InternalControlMessage.RAT_TIMER_EXPIRED); + System.out.println("RAT_TIMER_EXPIRED"); } }; //toDo set correct delays @@ -100,10 +108,10 @@ public void run() { LOG.debug("Send IDSCP_HELLO"); IdscpMessage idscpHello = IdscpMessageFactory. getIdscpHelloMessage(dat, this.localSupportedRatSuite, this.localExpectedRatSuite); - this.send(idscpHello); + sendFromFSM(idscpHello); fsmIsBusy.notify(); //enables fsm.onMessage() - LOG.debug("Set handshake timeout to 3 seconds"); - handshakeTimer.resetTimeout(3); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); return STATE_WAIT_FOR_HELLO; } @@ -133,8 +141,9 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { + handshakeTimer.cancelTimeout(); LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -143,8 +152,9 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { + handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -154,7 +164,7 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -163,6 +173,7 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { + handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); @@ -178,10 +189,10 @@ public void run() { LOG.debug("Calculate Rat mechanisms"); this.proverMechanism = getRatProverMechanism(this.localSupportedRatSuite, - (String [])idscpHello.getExpectedRatSuiteList().toArray()); + idscpHello.getExpectedRatSuiteList().toArray()); if (proverMechanism == null){ LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); @@ -189,10 +200,10 @@ public void run() { } this.verifierMechanism = getRatVerifierMechanism(localExpectedRatSuite, - (String [])idscpHello.getSupportedRatSuiteList().toArray()); + idscpHello.getSupportedRatSuiteList().toArray()); if (verifierMechanism == null){ LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); @@ -202,24 +213,27 @@ public void run() { LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat; - if (!idscpHello.hasDynamicAttributeToken() || !this.dapsDriver - .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray())){ + int datValidityPeriod; + if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod= this.dapsDriver + .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray()))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; } this.remoteDat = dat; - LOG.debug("Remote DAT is valid. Set dat timeout"); - //toDo set DAT timeout - datTimer.resetTimeout(3600); + LOG.debug("Remote DAT is valid. Set dat timeout to its validity period"); + datTimer.resetTimeout(datValidityPeriod); LOG.debug("Start RAT Prover and Verifier"); - this.ratVerifier = ratVerifierDriver.start(verifierMechanism, this); - this.ratProver = ratProverDriver.start(proverMechanism, this); + restartRatVerifierDriver(); + restartRatProverDriver(); - LOG.debug("Switch to state STATE_ESTABLISHED"); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_RAT; } @@ -255,11 +269,11 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - this.ratProver.terminate(); - this.ratVerifier.terminate(); + stopRatProverDriver(); + stopRatVerifierDriver(); this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -268,12 +282,12 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - this.ratProver.terminate(); - this.ratVerifier.terminate(); + stopRatProverDriver(); + stopRatVerifierDriver(); this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -291,7 +305,7 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_VERIFIER OK"); - ratTimer.resetTimeout(3600); + ratTimer.resetTimeout(this.ratTimeoutDelay); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -301,10 +315,10 @@ public void run() { event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - this.ratVerifier.terminate(); + stopRatVerifierDriver(); this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -314,11 +328,11 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_VERIFIER failed"); - this.ratProver.terminate(); + stopRatProverDriver(); this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -328,7 +342,7 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - send(event.getIdscpMessage()); + sendFromFSM(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -337,7 +351,7 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_VERIFIER"); - send(event.getIdscpMessage()); + sendFromFSM(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -346,8 +360,10 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( event -> { LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); - this.ratVerifier.terminate(); - send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + stopRatVerifierDriver(); + sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -356,10 +372,10 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - this.ratProver.terminate(); - this.ratVerifier.terminate(); + stopRatProverDriver(); + stopRatVerifierDriver(); this.datTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -369,7 +385,7 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - this.ratProver.delegate(event.getIdscpMessage()); + ratProverDriver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -378,7 +394,7 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - this.ratVerifier.delegate(event.getIdscpMessage()); + ratVerifierDriver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -387,8 +403,10 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver.restart(); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -397,8 +415,8 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - this.ratVerifier.terminate(); - this.ratProver.terminate(); + stopRatVerifierDriver(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); @@ -433,11 +451,11 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - this.ratVerifier.terminate(); + stopRatVerifierDriver(); this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -448,9 +466,9 @@ public void run() { event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); this.datTimer.cancelTimeout(); - this.ratVerifier.terminate(); + stopRatVerifierDriver(); this.handshakeTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -460,8 +478,9 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - this.ratVerifier.terminate(); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + stopRatVerifierDriver(); + datTimer.cancelTimeout(); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -471,8 +490,10 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( event -> { LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); - this.ratVerifier.terminate(); - send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + stopRatVerifierDriver(); + sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; @@ -482,8 +503,9 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_VERIFIER OK"); - //toDo set rat timeout - this.ratTimer.resetTimeout(3600); + this.handshakeTimer.cancelTimeout(); + LOG.debug("Start RAT Timer"); + this.ratTimer.resetTimeout(ratTimeoutDelay); LOG.debug("Switch to state STATE_ESTABLISHED"); notifyHandshakeCompleteLock(); return STATE_ESTABLISHED; @@ -496,7 +518,7 @@ public void run() { this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -506,7 +528,7 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_VERIFIER"); - send(event.getIdscpMessage()); + sendFromFSM(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); return STATE_WAIT_FOR_RAT_VERIFIER; } @@ -515,7 +537,7 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - this.ratVerifier.terminate(); + stopRatVerifierDriver(); this.datTimer.stop(); this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); @@ -527,8 +549,10 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -537,7 +561,7 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - this.ratVerifier.delegate(event.getIdscpMessage()); + ratVerifierDriver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); return STATE_WAIT_FOR_RAT_VERIFIER; } @@ -546,7 +570,9 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -579,12 +605,12 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - this.ratProver.terminate(); + stopRatProverDriver(); this.ratTimer.cancelTimeout(); this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -594,11 +620,11 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - this.ratProver.terminate(); + stopRatProverDriver(); this.ratTimer.cancelTimeout(); this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -608,10 +634,10 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - this.ratProver.terminate(); + stopRatProverDriver(); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -621,9 +647,10 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( event -> { LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); - this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_DAT_AND_RAT; @@ -643,12 +670,12 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_PROVER failed"); - this.ratProver.terminate(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -658,7 +685,7 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - send(event.getIdscpMessage()); + sendFromFSM(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -667,8 +694,11 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( event -> { LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); - send(IdscpMessageFactory.getIdscpReRatMessage("")); - this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); + this.ratTimer.cancelTimeout(); + restartRatVerifierDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; } @@ -677,7 +707,7 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - this.ratProver.terminate(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); @@ -690,8 +720,10 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver.restart(); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -700,7 +732,7 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - this.ratProver.delegate(event.getIdscpMessage()); + ratProverDriver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -709,7 +741,7 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - this.ratProver.restart(); + restartRatProverDriver(); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -740,7 +772,7 @@ public void run() { event -> { this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -751,7 +783,7 @@ public void run() { event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); this.handshakeTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -761,7 +793,7 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -780,22 +812,26 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( event -> { + this.handshakeTimer.cancelTimeout(); LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - if (!this.dapsDriver.verifyToken(dat)){ + int datValidityPeriod; + if (0 > (datValidityPeriod = this.dapsDriver.verifyToken(dat))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; } this.remoteDat = dat; LOG.debug("Remote DAT is valid. Set dat timeout"); - //toDo set DAT timeout - datTimer.resetTimeout(3600); + datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier - this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + restartRatVerifierDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); return STATE_WAIT_FOR_RAT_VERIFIER; @@ -805,8 +841,10 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -815,7 +853,9 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -848,10 +888,10 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - this.ratProver.terminate(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -861,9 +901,9 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - this.ratProver.terminate(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -873,8 +913,8 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - this.ratProver.terminate(); - send(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); + stopRatProverDriver(); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -885,6 +925,7 @@ public void run() { event -> { LOG.debug("Received RAT_PROVER OK"); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); + //toDo restart handshake timeout ???? return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } )); @@ -894,7 +935,7 @@ public void run() { LOG.error("RAT_PROVER failed"); this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; @@ -904,7 +945,7 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - send(event.getIdscpMessage()); + sendFromFSM(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -913,7 +954,7 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - this.ratProver.terminate(); + stopRatProverDriver(); this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); @@ -923,23 +964,27 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( event -> { + handshakeTimer.cancelTimeout(); LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - if (!this.dapsDriver.verifyToken(dat)){ - this.ratProver.terminate(); + int datValidityPeriod; + if (0 > (datValidityPeriod = this.dapsDriver.verifyToken(dat))){ + stopRatProverDriver(); LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - send(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); return STATE_CLOSED; } this.remoteDat = dat; LOG.debug("Remote DAT is valid. Set dat timeout"); - //toDo set DAT timeout - datTimer.resetTimeout(3600); + datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier - this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + restartRatVerifierDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); return STATE_WAIT_FOR_RAT; @@ -949,8 +994,8 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver.restart(); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -959,7 +1004,7 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - this.ratProver.delegate(event.getIdscpMessage()); + ratProverDriver.delegate(event.getIdscpMessage()); LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -968,7 +1013,7 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - this.ratProver.restart(); + restartRatProverDriver(); LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); return STATE_WAIT_FOR_DAT_AND_RAT; } @@ -1001,7 +1046,7 @@ public void run() { LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } @@ -1012,7 +1057,7 @@ public void run() { LOG.debug("Send IDSCP_CLOSE"); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); - send(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } @@ -1021,8 +1066,13 @@ public void run() { STATE_ESTABLISHED.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( event -> { LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); - send(IdscpMessageFactory.getIdscpReRatMessage("")); - this.ratVerifier = this.ratVerifierDriver.start(verifierMechanism, this); + this.ratTimer.cancelTimeout(); + sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); + restartRatVerifierDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); return STATE_WAIT_FOR_RAT_VERIFIER; } @@ -1030,8 +1080,13 @@ public void run() { STATE_ESTABLISHED.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( event -> { + this.ratTimer.cancelTimeout(); LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); - send(IdscpMessageFactory.getIdscpDatExpiredMessage()); + sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } @@ -1040,7 +1095,7 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + restartRatProverDriver(); LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -1049,8 +1104,12 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); - send(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - this.ratProver = this.ratProverDriver.start(proverMechanism, this); + sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); + restartRatProverDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); return STATE_WAIT_FOR_RAT_PROVER; } @@ -1128,6 +1187,40 @@ public void onControlMessage(InternalControlMessage controlMessage) { } } + @Override + public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + //only allow rat prover messages from current thread + Event e; + if (idscpMessage == null){ + e = new Event(controlMessage); + } else { + e = new Event(controlMessage, idscpMessage); + } + + synchronized (fsmIsBusy) { + if (Long.toString(Thread.currentThread().getId()).equals(currentRatProverId)) { + currentState = currentState.feedEvent(e); + } + } + } + + @Override + public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + //only allow rat verifier messages from current thread + Event e; + if (idscpMessage == null){ + e = new Event(controlMessage); + } else { + e = new Event(controlMessage, idscpMessage); + } + + synchronized (fsmIsBusy) { + if (Long.toString(Thread.currentThread().getId()).equals(currentRatVerifierId)) { + currentState = currentState.feedEvent(e); + } + } + } + public void terminate(){ LOG.info("Close idscp connection"); onControlMessage(InternalControlMessage.IDSCP_STOP); @@ -1157,6 +1250,11 @@ public void startIdscpHandshake() throws IDSCPv2Exception { } } + private void sendFromFSM(IdscpMessage msg){ + //send messages from fsm + secureChannel.send(msg.toByteArray()); + } + public void send(IdscpMessage msg){ //send messages from user only when idscp connection is established synchronized(fsmIsBusy){ @@ -1188,14 +1286,55 @@ private void notifyHandshakeCompleteLock(){ } //calculate Prover mechanism (strongest remote expected), returns null if no match was found - private String getRatProverMechanism(String[] localSupportedProver, String[] remoteExpectedVerifier){ + private String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ //toDo implement logic - return ""; + return "TPM_2"; } //calculate Verifier mechanism (strongest local expected), returns null if no match was found - private String getRatVerifierMechanism(String[] localExpectedVerifier, String[] remoteSupportedProver){ + private String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ //toDo implement logic - return ""; + return "TPM_2"; + } + + private void restartRatVerifierDriver(){ + //assume verifier mechanism is set + stopRatVerifierDriver(); + ratVerifierDriver = RatVerifierDriverRegistry.startRatVerifierDriver(verifierMechanism, this); + if (ratVerifierDriver == null){ + LOG.error("Cannot create instance of RAT_VERIFIER_DRIVER"); + currentRatVerifierId = ""; + onControlMessage(InternalControlMessage.ERROR); //toDo geht das? + } else { + currentRatVerifierId = Long.toString(ratVerifierDriver.getId()); + } + } + + private void stopRatVerifierDriver(){ + if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ + ratVerifierDriver.interrupt(); + ratVerifierDriver.terminate(); + } + } + + private void restartRatProverDriver(){ + //assume prover mechanism is set + stopRatVerifierDriver(); + ratProverDriver = RatProverDriverRegistry.startRatProverDriver(proverMechanism, this); + if (ratProverDriver == null){ + LOG.error("Cannot create instance of RAT_PROVER_DRIVER"); + currentRatProverId = ""; + onControlMessage(InternalControlMessage.ERROR); //toDo geht das? + } else { + currentRatProverId = Long.toString(ratProverDriver.getId()); + } } + + private void stopRatProverDriver(){ + if (ratProverDriver != null && ratProverDriver.isAlive()){ + ratProverDriver.interrupt(); + ratProverDriver.terminate(); + } + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index ccc0f88aa..6cfd1827f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -1,6 +1,10 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import de.fhg.aisec.ids.messages.IDSCPv2; + public interface FsmListener { void onMessage(byte[] data); void onControlMessage(InternalControlMessage controlMessage); + void onRatProverMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); + void onRatVerifierMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java new file mode 100644 index 000000000..708c2f6f1 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -0,0 +1,46 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.rat_registry; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; + +import java.util.concurrent.ConcurrentHashMap; + +public class RatProverDriverRegistry { + //toDO Reflections library + private static RatProverDriverRegistry instance; + private static ConcurrentHashMap> drivers = new ConcurrentHashMap<>(); + + private RatProverDriverRegistry(){} + + public static RatProverDriverRegistry getInstance(){ + if (instance == null){ + instance = new RatProverDriverRegistry(); + } + + return instance; + } + + public static RatProverDriver startRatProverDriver(String instance, FsmListener listener){ + Class driverClass = drivers.get(instance); + + try { + RatProverDriver driver = driverClass.getDeclaredConstructor().newInstance(); + driver.setListener(listener); + driver.start(); + return driver; + + } catch (Exception e) { + return null; + } + } + + + public void registerDriver(String instance, Class driverClass){ + drivers.put(instance, driverClass); + } + + public void unregisterDriver(String instance){ + drivers.remove(instance); + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java new file mode 100644 index 000000000..cb1536292 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java @@ -0,0 +1,46 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.rat_registry; + + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; + +import java.util.concurrent.ConcurrentHashMap; + +public class RatVerifierDriverRegistry { + private static RatVerifierDriverRegistry instance; + private static ConcurrentHashMap> drivers = new ConcurrentHashMap<>(); + + private RatVerifierDriverRegistry(){} + + public static RatVerifierDriverRegistry getInstance(){ + if (instance == null){ + instance = new RatVerifierDriverRegistry(); + } + + return instance; + } + + public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmListener listener){ + Class driverClass = drivers.get(mechanism); + + try { + RatVerifierDriver driver = driverClass.getDeclaredConstructor().newInstance(); + driver.setListener(listener); + driver.start(); + return driver; + + } catch (Exception e) { + return null; + } + } + + + public void registerDriver(String mechanism, Class driverClass){ + drivers.put(mechanism, driverClass); + } + + public void unregisterDriver(String instance){ + drivers.remove(instance); + } + +} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index ec8787bcf..05e1489db 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -1,15 +1,15 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2ProverImpl; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2VerifierImpl; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import java.util.concurrent.ConcurrentHashMap; @@ -20,11 +20,12 @@ public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings settings){ SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DapsDriver dapsDriver = new DefaultDapsDriver(); - RatVerifierDriver ratVerifier = new TPM2VerifierImpl(); - RatProverDriver ratProver = new TPM2ProverImpl(); + + RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); + RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, - dapsDriver, ratVerifier, ratProver, secureChannelDriver); + dapsDriver, secureChannelDriver); clientConfig.connect(settings); } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index cfc6b2d64..1245dfd61 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,19 +1,18 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2ProverImpl; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2VerifierImpl; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; - -import java.util.concurrent.ConcurrentHashMap; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { @@ -23,11 +22,12 @@ public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DapsDriver dapsDriver = new DefaultDapsDriver(); - RatVerifierDriver ratVerifier = new TPM2VerifierImpl(); - RatProverDriver ratProver = new TPM2ProverImpl(); + + RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); + RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, - dapsDriver, ratVerifier, ratProver, secureChannelDriver); + dapsDriver, secureChannelDriver); IDSCPv2Server idscPv2Server; try { idscPv2Server = idscpServerConfig.listen(serverSettings); From 8bbc081861cd786aa84d8177c7032ecbecd3e30f Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 27 Jan 2020 18:03:54 +0100 Subject: [PATCH 045/237] WIP: FSM add new timer to avoid race conditions, RAT bug fixed --- .../default_driver_impl/rat/TPM2Prover.java | 31 +++-------- .../default_driver_impl/rat/TPM2Verifier.java | 29 +++------- .../idscp_core/finite_state_machine/FSM.java | 31 ++++++++--- .../finite_state_machine/Timer.java | 53 +++++++++---------- .../finite_state_machine/TimerThread.java | 36 +++++++++++++ 5 files changed, 99 insertions(+), 81 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java index 706fd91fd..d42fbd406 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -1,7 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2.*; @@ -13,32 +12,18 @@ public TPM2Prover(){ @Override public void delegate(IdscpMessage message) { - //toDo blocking - successful = true; - synchronized (resultAvailableLock) { - resultAvailableLock.notify(); - } + //todo blocking } @Override public void run() { - /*fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, - IdscpMessageFactory.getIdscpRatProverMessage());*/ - while (running){ - synchronized (resultAvailableLock) { - /*try { - resultAvailableLock.wait(); - if (successful){ - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); - } else { - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - } - running = false; - } catch (InterruptedException e) { - e.printStackTrace(); - }*/ - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); - } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java index d6a326846..283152a71 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -1,8 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2; @@ -15,31 +13,16 @@ public TPM2Verifier(){ @Override public void delegate(IDSCPv2.IdscpMessage message) { //toDo blocking - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, - IdscpMessageFactory.getIdscpRatVerifierMessage()); - successful = true; - synchronized (resultAvailableLock) { - resultAvailableLock.notify(); - } + } @Override public void run(){ - while (running){ - synchronized (resultAvailableLock) { - /*try { - resultAvailableLock.wait(); - if (successful){ - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); - } else { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - } - running = false; - } catch (InterruptedException e) { - e.printStackTrace(); - }*/ - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); - } + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + e.printStackTrace(); } + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index fb516c219..2e3826bc0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -67,7 +67,7 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ @Override public void run() { //onControlMessage(InternalControlMessage.TIMEOUT); - System.out.println("Handshake timeout"); + System.out.println("HANDSHAKE_TIMER_EXPIRED"); } }; @@ -87,9 +87,9 @@ public void run() { } }; //toDo set correct delays - this.handshakeTimer = new Timer(handshakeTimeoutHandler); - this.datTimer = new Timer(datTimeoutHandler); - this.ratTimer = new Timer(ratTimeoutHandler); + this.handshakeTimer = new Timer(fsmIsBusy, handshakeTimeoutHandler); + this.datTimer = new Timer(fsmIsBusy, datTimeoutHandler); + this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); /* ------------- end timeout routines ------------- */ @@ -429,6 +429,11 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } return STATE_WAIT_FOR_RAT; } ); @@ -538,7 +543,7 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); stopRatVerifierDriver(); - this.datTimer.stop(); + this.datTimer.cancelTimeout(); this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); notifyHandshakeCompleteLock(); @@ -582,6 +587,11 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } return STATE_WAIT_FOR_RAT_VERIFIER; } ); @@ -751,6 +761,11 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } return STATE_WAIT_FOR_RAT_PROVER; } ); @@ -1144,6 +1159,11 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_ESTABLISHED"); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } return STATE_ESTABLISHED; } ); @@ -1336,5 +1356,4 @@ private void stopRatProverDriver(){ ratProverDriver.terminate(); } } - } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index cf420dd7a..df556a5a4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -1,45 +1,40 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import static java.util.concurrent.TimeUnit.*; +import java.util.concurrent.locks.ReentrantLock; public class Timer { - private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); - private ScheduledFuture timer; - private boolean isLocked = false; - private boolean isExecuting = false; - private Runnable timeoutHandler; + //toDo real time FIFO synchronization for whole state machine - public Timer(Runnable timeoutHandler){ + private TimerThread thread = null; + private final Object lock; + private final ReentrantLock mutex = new ReentrantLock(); + private final Runnable timeoutHandler; + + Timer(Object lock, Runnable timeoutHandler){ + this.lock = lock; this.timeoutHandler = timeoutHandler; } - public void cancelTimeout() { - if (!isLocked) { - if (isExecuting) { - timer.cancel(true); - } - } + void resetTimeout(int delay){ + cancelTimeout(); + start(delay); } - public boolean resetTimeout(int delay){ - if (!isLocked){ - if (isExecuting){ - timer.cancel(true); - } - timer = executor.schedule(timeoutHandler, delay, SECONDS); - return true; - } - return false; + public void start(int delay){ + mutex.lock(); + thread = new TimerThread(delay, timeoutHandler, lock); + thread.start(); + mutex.unlock(); } - public void stop(){ - if (!isLocked){ - executor.shutdownNow(); - isLocked = true; + void cancelTimeout(){ + mutex.lock(); + if (thread != null){ + thread.safeStop(); + thread = null; } + mutex.unlock(); } - } + diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java new file mode 100644 index 000000000..4901f4656 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -0,0 +1,36 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +public class TimerThread extends Thread{ + + private volatile boolean canceled = false; + private int delay; + private final Runnable timeoutHandler; + private final Object lock; + + TimerThread(int delay, Runnable timeoutHandler, Object lock){ + this.delay = delay; + this.timeoutHandler = timeoutHandler; + this.lock = lock; + } + + public void run(){ + try { + Thread.sleep(delay * 1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + if (canceled) + return; + + synchronized (lock){ + if (!canceled){ + timeoutHandler.run(); + } + } + } + + public void safeStop(){ + canceled = true; + } +} From 73aa3547f460dcfccd4cf13e0247999533166d5f Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 30 Jan 2020 16:56:35 +0100 Subject: [PATCH 046/237] Fix bug in Rat Verifier --- .../default_driver_impl/rat/TPM2Prover.java | 43 ++++++++++++++++--- .../default_driver_impl/rat/TPM2Verifier.java | 32 +++++++++++--- .../idscp_core/finite_state_machine/FSM.java | 3 +- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java index d42fbd406..9537550d5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -1,10 +1,29 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; +import de.fhg.aisec.ids.messages.IDSCPv2; import de.fhg.aisec.ids.messages.IDSCPv2.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * A RatProver dummy, that sends two incoming messages from the remote rat verifier and also sends two messages + */ public class TPM2Prover extends RatProverDriver { + private static final Logger LOG = LoggerFactory.getLogger(TPM2Prover.class); + + private BlockingQueue queue = new LinkedBlockingQueue<>(); public TPM2Prover(){ super(); @@ -12,18 +31,28 @@ public TPM2Prover(){ @Override public void delegate(IdscpMessage message) { - //todo blocking + queue.add(message); + LOG.debug("Delegated to prover"); } @Override public void run() { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); + int countDown = 2; + while (true){ + try { + sleep(2000); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, + IdscpMessageFactory.getIdscpRatProverMessage()); + System.out.println("Prover waits"); + IDSCPv2.IdscpMessage m = queue.take(); + System.out.println("Prover receives, send something"); + if (--countDown == 0) + break; + } catch (InterruptedException e) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); - } - } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java index 283152a71..d5a5eabe1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -1,10 +1,19 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; public class TPM2Verifier extends RatVerifierDriver { + private static final Logger LOG = LoggerFactory.getLogger(TPM2Verifier.class); + + private BlockingQueue queue = new LinkedBlockingQueue<>(); public TPM2Verifier(){ super(); @@ -12,16 +21,27 @@ public TPM2Verifier(){ @Override public void delegate(IDSCPv2.IdscpMessage message) { - //toDo blocking - + queue.add(message); + LOG.debug("Delegated to Verifier"); } @Override public void run(){ - try { - Thread.sleep(8000); - } catch (InterruptedException e) { - e.printStackTrace(); + int countDown = 2; + while (true){ + try { + sleep(2000); + LOG.debug("Verifier waits"); + IDSCPv2.IdscpMessage m = queue.take(); + LOG.debug("Verifier receives, send something"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, + IdscpMessageFactory.getIdscpRatProverMessage()); + if (--countDown == 0) + break; + } catch (InterruptedException e) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } } fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 2e3826bc0..b1f544b0a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -68,6 +68,7 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ public void run() { //onControlMessage(InternalControlMessage.TIMEOUT); System.out.println("HANDSHAKE_TIMER_EXPIRED"); + } }; @@ -1339,7 +1340,7 @@ private void stopRatVerifierDriver(){ private void restartRatProverDriver(){ //assume prover mechanism is set - stopRatVerifierDriver(); + stopRatProverDriver(); ratProverDriver = RatProverDriverRegistry.startRatProverDriver(proverMechanism, this); if (ratProverDriver == null){ LOG.error("Cannot create instance of RAT_PROVER_DRIVER"); From f100cd802825b00dbfd779a49f53710577aefd82 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 30 Jan 2020 18:33:38 +0100 Subject: [PATCH 047/237] Fix bugs in RAT Prover + Verifier --- .../default_driver_impl/rat/TPM2Prover.java | 6 +++--- .../default_driver_impl/rat/TPM2Verifier.java | 6 +++--- .../idscp_core/finite_state_machine/FSM.java | 16 +++++++++++----- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java index 9537550d5..55bbf061b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java @@ -40,12 +40,12 @@ public void run() { int countDown = 2; while (true){ try { - sleep(2000); + sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, IdscpMessageFactory.getIdscpRatProverMessage()); - System.out.println("Prover waits"); + LOG.debug("Prover waits"); IDSCPv2.IdscpMessage m = queue.take(); - System.out.println("Prover receives, send something"); + LOG.debug("Prover receives, send something"); if (--countDown == 0) break; } catch (InterruptedException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java index d5a5eabe1..c7d302715 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java @@ -30,12 +30,12 @@ public void run(){ int countDown = 2; while (true){ try { - sleep(2000); + sleep(1000); LOG.debug("Verifier waits"); IDSCPv2.IdscpMessage m = queue.take(); LOG.debug("Verifier receives, send something"); - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, - IdscpMessageFactory.getIdscpRatProverMessage()); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, + IdscpMessageFactory.getIdscpRatVerifierMessage()); if (--countDown == 0) break; } catch (InterruptedException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index b1f544b0a..581fdccec 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -54,7 +54,7 @@ public class FSM implements FsmListener{ private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private int ratTimeoutDelay = 3600; + private int ratTimeoutDelay = 10; public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ @@ -66,25 +66,24 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ Runnable handshakeTimeoutHandler = new Runnable() { @Override public void run() { - //onControlMessage(InternalControlMessage.TIMEOUT); System.out.println("HANDSHAKE_TIMER_EXPIRED"); - + onControlMessage(InternalControlMessage.TIMEOUT); } }; Runnable datTimeoutHandler = new Runnable() { @Override public void run() { - //onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); System.out.println("DAT_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); } }; Runnable ratTimeoutHandler = new Runnable() { @Override public void run() { - //onControlMessage(InternalControlMessage.RAT_TIMER_EXPIRED); System.out.println("RAT_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.REPEAT_RAT); } }; //toDo set correct delays @@ -1196,6 +1195,9 @@ public void onMessage(byte[] data){ } } currentState = currentState.feedEvent(event); + /*if (LOG.isDebugEnabled()) { + LOG.debug("Switched to state {}", currentState); + }*/ } } @@ -1221,6 +1223,8 @@ public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessa synchronized (fsmIsBusy) { if (Long.toString(Thread.currentThread().getId()).equals(currentRatProverId)) { currentState = currentState.feedEvent(e); + } else { + LOG.warn("An old or unknown identity calls onRatProverMessage()"); } } } @@ -1238,6 +1242,8 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMes synchronized (fsmIsBusy) { if (Long.toString(Thread.currentThread().getId()).equals(currentRatVerifierId)) { currentState = currentState.feedEvent(e); + } else { + LOG.warn("An old or unknown identity calls onRatVerifierMessage()"); } } } From 9e706067e9a3fa34c448495430b533dda8ea9585 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 3 Feb 2020 18:47:20 +0100 Subject: [PATCH 048/237] WIP: FSM Close and error handling --- .../client/DataAvailableListener.java | 2 + .../client/InputListenerThread.java | 16 +- .../secure_channel/client/TLSClient.java | 51 +++-- .../server/TLSServerThread.java | 55 +++--- .../idscp2/idscp_core/IDSCPv2Connection.java | 31 ++- .../idscp2/idscp_core/IdscpMsgListener.java | 3 +- .../configuration/IDSCPv2Configuration.java | 12 +- .../idscp_core/finite_state_machine/FSM.java | 179 ++++++++++++------ .../finite_state_machine/FsmListener.java | 2 + .../finite_state_machine/State.java | 10 + .../States/StateClosed.java | 15 ++ .../States/StateEstablished.java | 6 + .../States/StateWaitForDatAndRat.java | 6 + .../States/StateWaitForDatAndRatVerifier.java | 6 + .../States/StateWaitForHello.java | 6 + .../States/StateWaitForRat.java | 6 + .../States/StateWaitForRatProver.java | 6 + .../States/StateWaitForRatVerifier.java | 6 + .../finite_state_machine/Timer.java | 10 +- .../finite_state_machine/TimerThread.java | 13 +- .../secure_channel/SecureChannel.java | 27 ++- .../secure_channel/SecureChannelEndpoint.java | 2 - .../secure_channel/SecureChannelListener.java | 2 + .../src/test/java/IDSCPv2ClientInitiator.java | 2 +- .../src/test/java/IDSCPv2ServerInitiator.java | 3 +- 25 files changed, 314 insertions(+), 163 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java index 88fdd28bc..062bbd1ea 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -7,4 +7,6 @@ */ public interface DataAvailableListener { void onMessage(byte[] data); + void onError(); + void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index c0678e06f..15c605e8b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -25,7 +25,7 @@ public class InputListenerThread extends Thread implements InputListener { //private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); private DataInputStream in; - private ArrayList listeners = new ArrayList<>(); //no race conditions, could be empty list + private DataAvailableListener listener = null; //no race conditions, could be empty list private volatile boolean running = true; public InputListenerThread(InputStream in){ @@ -40,7 +40,7 @@ public void run(){ int len = in.readInt(); buf = new byte[len]; in.readFully(buf, 0, len); - notifyListeners(buf); + this.listener.onMessage(buf); } catch (SocketTimeoutException e) { //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye @@ -48,26 +48,20 @@ public void run(){ //continue; //toDo offset when timeout while reading ??? } catch (EOFException e){ - notifyListeners(TlsConstants.END_OF_STREAM.getBytes()); + listener.onClose(); running = false; //terminate } catch (IOException e) { - //e.printStackTrace(); + listener.onError(); running = false; } } - listeners.clear(); } @Override public void register(DataAvailableListener listener) { - listeners.add(listener); + this.listener = listener; } - private void notifyListeners(byte[] bytes) { - for (DataAvailableListener listener : listeners){ - listener.onMessage(bytes); - } - } @Override public void safeStop() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 13b99667b..7dc721bdf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -37,8 +37,6 @@ * * close() disconnects the client * - * setConnectionId(ConnectionId) set the internal connectionId, which is used for notifying the IDSCPv2Configuration - * when the server quits the connection * * handshakeCompleted() create a secureChannel, including this client; start inputListenerThread and transfer * the secureChannel to the IDSCPv2Configuration @@ -60,8 +58,7 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private SecureChannelListener listener; //race conditions are avoided using CountDownLatch private CountDownLatch listenerLatch = new CountDownLatch(1); private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in constructor - private CountDownLatch connectionIdLatch = new CountDownLatch(1); - private String connectionId = "empty_connection_id"; + public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) throws IOException, KeyManagementException, NoSuchAlgorithmException{ @@ -158,9 +155,23 @@ private void disconnect(){ } @Override - public void setConnectionId(String connectionId){ - this.connectionId = connectionId; - connectionIdLatch.countDown(); + public void onClose(){ + try { + listenerLatch.await(); + listener.onClose(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + @Override + public void onError(){ + try { + listenerLatch.await(); + listener.onError(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } @Override @@ -179,7 +190,7 @@ public void send(byte[] data){ LOG.debug("Send message: {}", new String(data)); } catch (IOException e){ LOG.warn("Client cannot send data"); - e.printStackTrace(); + //e.printStackTrace(); } } } @@ -205,25 +216,11 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) @Override public void onMessage(byte[] data) { - if ((new String(data, StandardCharsets.UTF_8)).equals(TlsConstants.END_OF_STREAM)){ - //End of stream, connection is not available anymore - LOG.debug("Client is terminating after server disconnected"); - disconnect(); - - try { - connectionIdLatch.await(); - callback.connectionClosedHandler(this.connectionId); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } - - } else { - try{ - listenerLatch.await(); - listener.onMessage(data); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } + try{ + listenerLatch.await(); + listener.onMessage(data); + } catch (InterruptedException e){ + Thread.currentThread().interrupt(); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index fad3f9190..853b25a08 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -30,8 +30,6 @@ * * close() disconnects the serverThread * - * setConnectionId(ConnectionId) set the internal connectionId, which is used for notifying the IDSCPv2Configuration - * when the client quits the connection * * handshakeCompleted() create a secureChannel, including this serverThread and provides it to the IDSCPv2Config * @@ -48,8 +46,6 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private volatile boolean running = true; private DataInputStream in; private DataOutputStream out; - private String connectionId = "empty_connection_id"; //race condition avoided using CountDownLatch - private CountDownLatch connectionIdLatch = new CountDownLatch(1); private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch private IDSCPv2Callback configCallback; //no race conditions private IdscpConnectionListener idscpServerCallback; //no race conditions @@ -72,12 +68,6 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene } } - @Override - public void setConnectionId(String connectionId){ - this.connectionId = connectionId; - connectionIdLatch.countDown(); - } - @Override public void run(){ //wait for new data while running @@ -93,31 +83,18 @@ public void run(){ //timeout catches safeStop() call and allows to send server_goodbye //alternative: close sslSocket and catch SocketException //continue - } catch (SSLException e) { - LOG.error("SSL error"); - e.printStackTrace(); - running = false; - connectionIdLatch.countDown(); - return; } catch (EOFException e){ + onClose(); running = false; - connectionIdLatch.countDown(); } catch (IOException e){ - e.printStackTrace(); + onError(); running = false; - connectionIdLatch.countDown(); } } + closeSockets(); + } - try { - connectionIdLatch.await(); - idscpServerCallback.connectionClosedHandler(this.connectionId); - configCallback.connectionClosedHandler(this.connectionId); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } - - LOG.trace("ServerThread is terminating"); + private void closeSockets(){ try { out.close(); in.close(); @@ -130,6 +107,7 @@ public void run(){ public void send(byte[] data) { if (!isConnected()){ LOG.error("Server cannot send data because socket is not connected"); + closeSockets(); } else { try { out.writeInt(data.length); @@ -137,11 +115,30 @@ public void send(byte[] data) { out.flush(); LOG.trace("Send message: " + new String(data)); } catch (IOException e){ - LOG.error("Server cannot send data. {}",e.getMessage()); + LOG.error("ServerThread cannot send data."); + closeSockets(); } } } + private void onClose(){ + try { + listenerLatch.await(); + listener.onClose(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void onError(){ + try { + listenerLatch.await(); + listener.onError(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + @Override public void close() { safeStop(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index f67eed373..09e419e6e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -1,10 +1,15 @@ package de.fhg.aisec.ids.idscp2.idscp_core; +import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + /** * The IDSCPv2 Connection class * @@ -23,24 +28,40 @@ public class IDSCPv2Connection implements IdscpMsgListener { private FSM fsm; private String connectionId; + private IDSCPv2Initiator user; + private IdscpConnectionListener server; - public IDSCPv2Connection(FSM fsm, String connectionId){ + public IDSCPv2Connection(FSM fsm, String connectionId, IDSCPv2Initiator user, IdscpConnectionListener server){ this.fsm = fsm; this.connectionId = connectionId; + this.user = user; + this.server = server; } public void close() { + if (server != null) { + server.connectionClosedHandler(connectionId); + } fsm.terminate(); } - public void send(IdscpMessage msg) { + public void send(byte[] msg) { LOG.debug("Send idscp message"); - fsm.send(msg); + fsm.send(IdscpMessageFactory.getIdscpDataMessage(msg)); + } + + @Override + public void onMessage(byte[] msg) { + LOG.info("Received new IDSCP Message: " + Arrays.toString(msg)); } @Override - public void onMessage(IdscpMessage msg) { - LOG.info("Received new IDSCP Message: " + msg.toString()); + public void onClose() { + LOG.debug("Connection with id {} has been closed, notify user", connectionId); + user.connectionClosedHandler(connectionId); + if (server != null) { + server.connectionClosedHandler(connectionId); + } } public boolean isConnected() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java index a3a2a0b22..1171fdec1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java @@ -3,5 +3,6 @@ import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; public interface IdscpMsgListener { - void onMessage(IdscpMessage message); + void onMessage(byte[] data); + void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index 26d17fd45..d6c284c6f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -68,9 +68,6 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver); - String connectionId = UUID.randomUUID().toString(); - //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock - fsm.setEndpointConnectionId(connectionId); try { fsm.startIdscpHandshake(); //blocking until handshake is done @@ -78,7 +75,8 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { return; } - IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId); + String connectionId = UUID.randomUUID().toString(); + IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId, user, null); fsm.registerMessageListener(newConnection); LOG.info("A new IDSCPv2 connection with id {} was created", connectionId); user.newConnectionHandler(newConnection); @@ -90,9 +88,6 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnect if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver); - String connectionId = UUID.randomUUID().toString(); - //important so set endpoint connection id before fsm.startIdscpHandshake() to avoid deadlock - fsm.setEndpointConnectionId(connectionId); try { fsm.startIdscpHandshake(); //blocking until handshake is done @@ -101,7 +96,8 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnect } //create new IDSCPv2Connection - IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId); + String connectionId = UUID.randomUUID().toString(); + IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId, user, idscpServer); fsm.registerMessageListener(newConnection); LOG.info("A new idscpv2 connection with id {} was created", connectionId); idscpServer.newConnectionHandler(newConnection); //bind connection to idscp server diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 581fdccec..ce71a31c1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -8,11 +8,14 @@ import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import de.fhg.aisec.ids.messages.IDSCPv2; import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); @@ -43,8 +46,11 @@ public class FSM implements FsmListener{ private IdscpMsgListener listener = null; private final CountDownLatch listenerLatch = new CountDownLatch(1); - private final Object idscpHandshakeLock = new Object(); - private final Object fsmIsBusy = new Object(); + private final ReentrantLock fsmIsBusy = new ReentrantLock(true); //use a fair synchronization lock (FIFO) + private final Condition onMessageBlock = fsmIsBusy.newCondition(); + private final Condition idscpHandshakeLock = fsmIsBusy.newCondition(); + private boolean handshakeResultAvailable = false; + private boolean fsmIsClosed = false; //toDo cipher suites private String[] localSupportedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; @@ -62,6 +68,7 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ this.dapsDriver = dapsDriver; secureChannel.setFsm(this); + /* ------------- Timeout Handler Routines ------------*/ Runnable handshakeTimeoutHandler = new Runnable() { @Override @@ -92,24 +99,23 @@ public void run() { this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); /* ------------- end timeout routines ------------- */ - /* ----------- Protocol Transitions ---------- */ /*--------------------------------------------------- - * STATE_CLOSED - Transition Description - * --------------------------------------------------- - * onICM: start_handshake --> {send IDSCP_HELLO, set handshake_timeout} --> STATE_WAIT_FOR_HELLO - * ALL_OTHER_MESSAGES ---> STATE_CLOSED - * --------------------------------------------------- */ + * STATE_CLOSED - Transition Description + * --------------------------------------------------- + * onICM: start_handshake --> {send IDSCP_HELLO, set handshake_timeout} --> STATE_WAIT_FOR_HELLO + * ALL_OTHER_MESSAGES ---> STATE_CLOSED + * --------------------------------------------------- */ STATE_CLOSED.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( event -> { LOG.debug("Get DAT Token vom DAT_DRIVER"); byte[] dat = this.dapsDriver.getToken(); LOG.debug("Send IDSCP_HELLO"); - IdscpMessage idscpHello = IdscpMessageFactory. + IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. getIdscpHelloMessage(dat, this.localSupportedRatSuite, this.localExpectedRatSuite); sendFromFSM(idscpHello); - fsmIsBusy.notify(); //enables fsm.onMessage() + onMessageBlock.signalAll(); //enables fsm.onMessage() LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); @@ -124,7 +130,7 @@ public void run() { notifyHandshakeCompleteLock(); return STATE_CLOSED; } - ); + ); /*--------------------------------------------------- * STATE_WAIT_FOR_HELLO - Transition Description @@ -234,7 +240,6 @@ public void run() { handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_RAT; } )); @@ -429,11 +434,6 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } return STATE_WAIT_FOR_RAT; } ); @@ -500,7 +500,6 @@ public void run() { LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); - notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; } )); @@ -587,11 +586,6 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } return STATE_WAIT_FOR_RAT_VERIFIER; } ); @@ -662,7 +656,6 @@ public void run() { LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); - notifyHandshakeCompleteLock(); return STATE_WAIT_FOR_DAT_AND_RAT; } )); @@ -761,11 +754,6 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } return STATE_WAIT_FOR_RAT_PROVER; } ); @@ -1061,7 +1049,8 @@ public void run() { LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); this.datTimer.cancelTimeout(); this.ratTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", + IdscpClose.CloseCause.ERROR)); LOG.debug("Switch to state STATE_CLOSED"); return STATE_CLOSED; } @@ -1134,7 +1123,7 @@ public void run() { event -> { try { this.listenerLatch.await(); - this.listener.onMessage(event.getIdscpMessage()); + this.listener.onMessage(event.getIdscpMessage().getIdscpData().toByteArray()); LOG.debug("Idscp data was passed to connection listener"); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); @@ -1159,11 +1148,6 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_ESTABLISHED"); - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } return STATE_ESTABLISHED; } ); @@ -1186,27 +1170,32 @@ public void onMessage(byte[] data){ Event event = new Event(message); //must wait when fsm is in state STATE_CLOSED --> wait() will be notified when fsm is leaving STATE_CLOSED - synchronized (fsmIsBusy){ + fsmIsBusy.lock(); + try { while (currentState == STATE_CLOSED){ try { - fsmIsBusy.wait(); + onMessageBlock.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } - currentState = currentState.feedEvent(event); - /*if (LOG.isDebugEnabled()) { - LOG.debug("Switched to state {}", currentState); - }*/ + feedEvent(event); + } finally { + fsmIsBusy.unlock(); } + } @Override public void onControlMessage(InternalControlMessage controlMessage) { //create Internal Control Message Event and pass it to current state and update new state Event e = new Event(controlMessage); - synchronized (fsmIsBusy){ - currentState = currentState.feedEvent(e); + + fsmIsBusy.lock(); + try { + feedEvent(e); + } finally { + fsmIsBusy.unlock(); } } @@ -1220,12 +1209,15 @@ public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessa e = new Event(controlMessage, idscpMessage); } - synchronized (fsmIsBusy) { + fsmIsBusy.lock(); + try { if (Long.toString(Thread.currentThread().getId()).equals(currentRatProverId)) { - currentState = currentState.feedEvent(e); + feedEvent(e); } else { LOG.warn("An old or unknown identity calls onRatProverMessage()"); } + } finally { + fsmIsBusy.unlock(); } } @@ -1239,12 +1231,37 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMes e = new Event(controlMessage, idscpMessage); } - synchronized (fsmIsBusy) { + fsmIsBusy.lock(); + try{ if (Long.toString(Thread.currentThread().getId()).equals(currentRatVerifierId)) { - currentState = currentState.feedEvent(e); + feedEvent(e); } else { LOG.warn("An old or unknown identity calls onRatVerifierMessage()"); } + } finally { + fsmIsBusy.unlock(); + } + } + + private void feedEvent(Event e){ + State prevState = currentState; + currentState = currentState.feedEvent(e); + if (!prevState.equals(STATE_CLOSED) && currentState.equals(STATE_CLOSED)){ + //fsm is closed, stop and free all resources, drivers and lock fsm forever + secureChannel.close(); + dapsDriver = null; + + this.datTimer.cancelTimeout(); + this.datTimer = null; + this.ratTimer.cancelTimeout(); + this.ratTimer = null; + this.handshakeTimer.cancelTimeout(); + this.handshakeTimer = null; + + this.stopRatProverDriver(); + this.stopRatVerifierDriver(); + + fsmIsClosed = true; } } @@ -1256,14 +1273,20 @@ public void terminate(){ } public void startIdscpHandshake() throws IDSCPv2Exception { - if (currentState.equals(STATE_CLOSED)){ - //trigger handshake init - onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); + fsmIsBusy.lock(); + try { + if (currentState.equals(STATE_CLOSED)) { + if (fsmIsClosed) { + throw new IDSCPv2Exception("FSM is in a final closed state forever"); + } + + //trigger handshake init + onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); - try { //wait until handshake was successful or failed - synchronized (idscpHandshakeLock) { - idscpHandshakeLock.wait(); + if (!handshakeResultAvailable) { + System.out.println("lock handshake"); + idscpHandshakeLock.await(); } if (!isConnected()){ @@ -1271,9 +1294,14 @@ public void startIdscpHandshake() throws IDSCPv2Exception { throw new IDSCPv2Exception("Handshake failed"); } - } catch (InterruptedException e) { - throw new IDSCPv2Exception("Handshake failed because thread was interrupted"); + + } else { + throw new IDSCPv2Exception("Handshake has already been started"); } + } catch (InterruptedException e) { + throw new IDSCPv2Exception("Handshake failed because thread was interrupted"); + } finally { + fsmIsBusy.unlock(); } } @@ -1282,14 +1310,39 @@ private void sendFromFSM(IdscpMessage msg){ secureChannel.send(msg.toByteArray()); } + @Override + public void onError(){ + onControlMessage(InternalControlMessage.ERROR); + try { + listenerLatch.await(); + listener.onClose(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public void onClose(){ + onControlMessage(InternalControlMessage.ERROR); //toDo + try { + listenerLatch.await(); + listener.onClose(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + public void send(IdscpMessage msg){ //send messages from user only when idscp connection is established - synchronized(fsmIsBusy){ + fsmIsBusy.lock(); + try{ if(isConnected()){ secureChannel.send(msg.toByteArray()); } else { LOG.error("Cannot send IDSCP_DATA because protocol is not established"); } + } finally { + fsmIsBusy.unlock(); } } @@ -1302,13 +1355,13 @@ public void registerMessageListener(IdscpMsgListener listener){ listenerLatch.countDown(); } - public void setEndpointConnectionId(String id){ - this.secureChannel.setEndpointConnectionId(id); - } - private void notifyHandshakeCompleteLock(){ - synchronized (idscpHandshakeLock){ - idscpHandshakeLock.notify(); + fsmIsBusy.lock(); + try { + handshakeResultAvailable = true; + idscpHandshakeLock.signal(); + } finally { + fsmIsBusy.unlock(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index 6cfd1827f..0a2dc0659 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -7,4 +7,6 @@ public interface FsmListener { void onControlMessage(InternalControlMessage controlMessage); void onRatProverMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); void onRatVerifierMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); + void onError(); + void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 75f540537..92ea6cce6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -30,4 +30,14 @@ void addTransition(Object k, Transition t){ void setNoTransitionHandler(Function noTransitionHandler) { this.noTransitionHandler = noTransitionHandler; } +/* + protected void runEntryCode(){ + + } + + protected void runExitCode(){ + + } + + */ } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java new file mode 100644 index 000000000..02f973e16 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java @@ -0,0 +1,15 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + + + +public class StateClosed extends State { + + public StateClosed(FSM fsm){ + + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java new file mode 100644 index 000000000..7180c462f --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateEstablished extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java new file mode 100644 index 000000000..f90e5b829 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForDatAndRat extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java new file mode 100644 index 000000000..9dd6a0c95 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForDatAndRatVerifier extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java new file mode 100644 index 000000000..dec7a21bf --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForHello extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java new file mode 100644 index 000000000..790c69e77 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForRat extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java new file mode 100644 index 000000000..0c0f11ef2 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForRatProver extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java new file mode 100644 index 000000000..842e056b5 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java @@ -0,0 +1,6 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; + +public class StateWaitForRatVerifier extends State { +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index df556a5a4..9eb2e25b5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -7,12 +7,12 @@ public class Timer { //toDo real time FIFO synchronization for whole state machine private TimerThread thread = null; - private final Object lock; - private final ReentrantLock mutex = new ReentrantLock(); + private final ReentrantLock fsmIsBusy; + private final ReentrantLock mutex = new ReentrantLock(true); private final Runnable timeoutHandler; - Timer(Object lock, Runnable timeoutHandler){ - this.lock = lock; + Timer(ReentrantLock fsmIsBusy, Runnable timeoutHandler){ + this.fsmIsBusy = fsmIsBusy; this.timeoutHandler = timeoutHandler; } @@ -23,7 +23,7 @@ void resetTimeout(int delay){ public void start(int delay){ mutex.lock(); - thread = new TimerThread(delay, timeoutHandler, lock); + thread = new TimerThread(delay, timeoutHandler, fsmIsBusy); thread.start(); mutex.unlock(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index 4901f4656..bfdd5ac74 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -1,16 +1,18 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +import java.util.concurrent.locks.ReentrantLock; + public class TimerThread extends Thread{ private volatile boolean canceled = false; private int delay; private final Runnable timeoutHandler; - private final Object lock; + private final ReentrantLock fsmIsBusy; - TimerThread(int delay, Runnable timeoutHandler, Object lock){ + TimerThread(int delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy){ this.delay = delay; this.timeoutHandler = timeoutHandler; - this.lock = lock; + this.fsmIsBusy = fsmIsBusy; } public void run(){ @@ -23,10 +25,13 @@ public void run(){ if (canceled) return; - synchronized (lock){ + fsmIsBusy.lock(); + try { if (!canceled){ timeoutHandler.run(); } + } finally { + fsmIsBusy.unlock(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index 917a37f95..73e90f072 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -52,13 +52,30 @@ public void onMessage(byte[] data){ } } - public boolean isConnected(){ - return endpoint.isConnected(); + @Override + public void onError() { + //tell fsm an error occurred in secure channel + try { + fsmLatch.await(); + fsm.onError(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + @Override + public void onClose() { + //tell fsm secure channel received EOF + try { + fsmLatch.await(); + fsm.onClose(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } - public void setEndpointConnectionId(String id){ - this.endpoint.setConnectionId(id); - //deadlock is resolved + public boolean isConnected(){ + return endpoint.isConnected(); } public void setFsm(FsmListener fsm) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index dd27ccf5e..f3134434c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -10,7 +10,6 @@ * void onMessage(int len, byte[]) receive new raw data from connected endpoint * void send(byte[]) send byte array to connected endpoint * boolean isConnected() check if endpoint is connected - * void setConnectionId(String id) * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -19,5 +18,4 @@ public interface SecureChannelEndpoint { void onMessage(byte[] bytes); void send(byte[] bytes); boolean isConnected(); - void setConnectionId(String id); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java index 8ad5218ab..e4a7b85fc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java @@ -2,4 +2,6 @@ public interface SecureChannelListener { void onMessage(byte[] data); + void onError(); + void onClose(); } diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 05e1489db..f3ca7312d 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -33,7 +33,7 @@ public void init(IDSCPv2Settings settings){ @Override public void newConnectionHandler(IDSCPv2Connection connection) { this.connections.put(connection.getConnectionId(), connection); - //connection.close(); + System.out.println("New connection with id " + connection.getConnectionId()); } @Override diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 1245dfd61..f326530b3 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -46,7 +46,7 @@ public void init(IDSCPv2Settings serverSettings) { @Override public void newConnectionHandler(IDSCPv2Connection connection) { - //connections.put(connection.getConnectionId(), connection); + System.out.println("New connection with id " + connection.getConnectionId()); } @Override @@ -57,6 +57,5 @@ public void errorHandler(String error) { @Override public void connectionClosedHandler(String connectionId) { System.out.println("Connection with id " + connectionId + " has been closed"); - //connections.remove(connectionId); } } From 25fe28cca8144b6e196a2a69a128e0410639de37 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 6 Feb 2020 13:52:33 +0100 Subject: [PATCH 049/237] FIX Timer Thread lifetime bug, Simplify closing --- .../secure_channel/client/TLSClient.java | 9 +- .../server/TLSServerThread.java | 2 + .../idscp_core/finite_state_machine/FSM.java | 228 +++++++----------- .../finite_state_machine/TimerThread.java | 10 +- .../idscp_server/IDSCPv2Server.java | 6 +- .../src/test/java/IDSCPv2ClientInitiator.java | 6 +- .../src/test/java/IDSCPv2ServerInitiator.java | 8 +- idscp2/src/test/java/RunTLSClient.java | 1 - 8 files changed, 108 insertions(+), 162 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 7dc721bdf..3e957daec 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -149,7 +149,7 @@ private void disconnect(){ try { clientSocket.close(); } catch (IOException e) { - //e.printStackTrace(); + //nothing to do } } } @@ -181,7 +181,8 @@ public void close() { public void send(byte[] data){ if (!isConnected()){ - LOG.warn("Client cannot send data because socket is not connected"); + LOG.error("Client cannot send data because socket is not connected"); + onError(); } else { try { out.writeInt(data.length); @@ -189,8 +190,8 @@ public void send(byte[] data){ out.flush(); LOG.debug("Send message: {}", new String(data)); } catch (IOException e){ - LOG.warn("Client cannot send data"); - //e.printStackTrace(); + LOG.error("Client cannot send data"); + onError(); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 853b25a08..bd1bad248 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -108,6 +108,7 @@ public void send(byte[] data) { if (!isConnected()){ LOG.error("Server cannot send data because socket is not connected"); closeSockets(); + onError(); } else { try { out.writeInt(data.length); @@ -117,6 +118,7 @@ public void send(byte[] data) { } catch (IOException e){ LOG.error("ServerThread cannot send data."); closeSockets(); + onError(); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index ce71a31c1..03e8e5404 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -127,7 +127,6 @@ public void run() { event -> { LOG.debug("No transition available for given event " + event.toString()); LOG.debug("Stay in state STATE_CLOSED"); - notifyHandshakeCompleteLock(); return STATE_CLOSED; } ); @@ -135,7 +134,7 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_HELLO - Transition Description * --------------------------------------------------- - * onICM: error --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: error --> {} ---> STATE_CLOSED * onICM: stop --> {send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED * onMessage: IDSCP_CLOSE---> {} ---> STATE_CLOSED @@ -148,10 +147,9 @@ public void run() { STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { handshakeTimer.cancelTimeout(); - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -162,7 +160,7 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -172,7 +170,7 @@ public void run() { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -182,7 +180,7 @@ public void run() { handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -201,7 +199,7 @@ public void run() { sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } @@ -212,7 +210,7 @@ public void run() { sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } @@ -225,7 +223,7 @@ public void run() { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -255,7 +253,7 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_RAT - Transition Description * --------------------------------------------------- - * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED + * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_WAIT_FOR_RAT_PROVER @@ -273,28 +271,19 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - stopRatProverDriver(); - stopRatVerifierDriver(); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - stopRatProverDriver(); - stopRatVerifierDriver(); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -320,12 +309,9 @@ public void run() { event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - stopRatVerifierDriver(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -333,13 +319,10 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_VERIFIER failed"); - stopRatProverDriver(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -377,12 +360,9 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - stopRatProverDriver(); - stopRatVerifierDriver(); - this.datTimer.cancelTimeout(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -420,12 +400,8 @@ public void run() { STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - stopRatVerifierDriver(); - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -441,7 +417,7 @@ public void run() { /*--------------------------------------------------- * STATE_WAIT_FOR_RAT_VERIFIER - Transition Description * --------------------------------------------------- - * onICM: error ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: error ---> {stop RAT_VERIFIER} ---> STATE_CLOSED * onICM: close ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, cancel ratV} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED @@ -456,26 +432,19 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - stopRatVerifierDriver(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - this.datTimer.cancelTimeout(); - stopRatVerifierDriver(); - this.handshakeTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -483,11 +452,9 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - stopRatVerifierDriver(); - datTimer.cancelTimeout(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -511,7 +478,7 @@ public void run() { LOG.debug("Start RAT Timer"); this.ratTimer.resetTimeout(ratTimeoutDelay); LOG.debug("Switch to state STATE_ESTABLISHED"); - notifyHandshakeCompleteLock(); + connectionEstablished(); return STATE_ESTABLISHED; } )); @@ -519,12 +486,10 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_VERIFIER failed"); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -541,11 +506,8 @@ public void run() { STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - stopRatVerifierDriver(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -594,7 +556,7 @@ public void run() { * STATE_WAIT_FOR_RAT_PROVER - Transition Description * --------------------------------------------------- * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER, timeouts.terminate()} ---> STATE_CLOSED - * onICM: error ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT * onICM: rat_prover_ok ---> {} ---> STATE_ESTABLISHED @@ -609,28 +571,19 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - stopRatProverDriver(); - this.ratTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - stopRatProverDriver(); - this.ratTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - this.handshakeTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -638,12 +591,9 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - stopRatProverDriver(); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -665,7 +615,7 @@ public void run() { LOG.debug("Received RAT_PROVER OK"); this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_ESTABLISHED"); - notifyHandshakeCompleteLock(); + connectionEstablished(); return STATE_ESTABLISHED; } )); @@ -673,14 +623,10 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_PROVER failed"); - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -710,12 +656,8 @@ public void run() { STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -762,7 +704,7 @@ public void run() { * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description * --------------------------------------------------- * onICM: stop ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: error ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: error ---> {} ---> STATE_CLOSED * onICM: timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED * onMessage: IDSCP_DAT(success) --> {verify DAT, set det_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFEIER @@ -773,22 +715,19 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - this.handshakeTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -798,7 +737,7 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -806,9 +745,8 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -824,7 +762,7 @@ public void run() { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -876,7 +814,7 @@ public void run() { * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description * --------------------------------------------------- * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED - * onICM: error ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED @@ -891,24 +829,19 @@ public void run() { * --------------------------------------------------- */ STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("An internal control error occurred, send IDSC_CLOSE"); - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", IdscpClose.CloseCause.ERROR)); + LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -916,10 +849,9 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - stopRatProverDriver(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -936,11 +868,10 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( event -> { LOG.error("RAT_PROVER failed"); - this.handshakeTimer.cancelTimeout(); LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -957,10 +888,8 @@ public void run() { STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); - stopRatProverDriver(); - this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } )); @@ -973,11 +902,10 @@ public void run() { byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); int datValidityPeriod; if (0 > (datValidityPeriod = this.dapsDriver.verifyToken(dat))){ - stopRatProverDriver(); LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - notifyHandshakeCompleteLock(); + connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -1034,7 +962,7 @@ public void run() { * STATE_ESTABLISHED - Transition Description * --------------------------------------------------- * onICM: error ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: stop ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop ---> {timeouts.cancel()} ---> STATE_CLOSED * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER @@ -1046,12 +974,9 @@ public void run() { * --------------------------------------------------- */ STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( event -> { - LOG.debug("Error occurred, send IDSCP_CLOSE and close idscp connection"); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Error occurred", - IdscpClose.CloseCause.ERROR)); + LOG.debug("Error occurred, close idscp connection"); LOG.debug("Switch to state STATE_CLOSED"); + connectionClosed(); return STATE_CLOSED; } )); @@ -1059,10 +984,9 @@ public void run() { STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_CLOSE"); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); + connectionClosed(); return STATE_CLOSED; } )); @@ -1137,9 +1061,8 @@ public void run() { STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Receive IDSCP_CLOSED"); - datTimer.cancelTimeout(); - ratTimer.cancelTimeout(); LOG.debug("Switch to STATE_CLOSED"); + connectionClosed(); return STATE_CLOSED; } )); @@ -1284,8 +1207,7 @@ public void startIdscpHandshake() throws IDSCPv2Exception { onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); //wait until handshake was successful or failed - if (!handshakeResultAvailable) { - System.out.println("lock handshake"); + while (!handshakeResultAvailable) { idscpHandshakeLock.await(); } @@ -1294,7 +1216,6 @@ public void startIdscpHandshake() throws IDSCPv2Exception { throw new IDSCPv2Exception("Handshake failed"); } - } else { throw new IDSCPv2Exception("Handshake has already been started"); } @@ -1313,22 +1234,43 @@ private void sendFromFSM(IdscpMessage msg){ @Override public void onError(){ onControlMessage(InternalControlMessage.ERROR); - try { - listenerLatch.await(); - listener.onClose(); - } catch (InterruptedException e) { - e.printStackTrace(); - } } @Override public void onClose(){ - onControlMessage(InternalControlMessage.ERROR); //toDo + onControlMessage(InternalControlMessage.ERROR); + } + + private void connectionEstablished(){ + fsmIsBusy.lock(); try { - listenerLatch.await(); - listener.onClose(); + if (!handshakeResultAvailable) { + notifyHandshakeCompleteLock(); + } + } finally { + fsmIsBusy.unlock(); + } + } + + private void connectionClosed(){ + fsmIsBusy.lock(); + try { + if (handshakeResultAvailable){ + listenerLatch.await(); + listener.onClose(); + } else { + notifyHandshakeCompleteLock(); + } + //terminate timeouts, rat drivers + this.handshakeTimer.cancelTimeout(); + this.datTimer.cancelTimeout(); + this.ratTimer.cancelTimeout(); + stopRatVerifierDriver(); + stopRatProverDriver(); } catch (InterruptedException e) { - e.printStackTrace(); + Thread.currentThread().interrupt(); + } finally { + fsmIsBusy.unlock(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index bfdd5ac74..2efc7109c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -19,11 +19,14 @@ public void run(){ try { Thread.sleep(delay * 1000); } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; + if (!canceled) { + Thread.currentThread().interrupt(); + } } - if (canceled) + + if (canceled) { return; + } fsmIsBusy.lock(); try { @@ -37,5 +40,6 @@ public void run(){ public void safeStop(){ canceled = true; + this.interrupt(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java index ac5aad82b..600998a95 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java @@ -39,10 +39,8 @@ public void terminate(){ public void terminateAllSessions(){ for (IDSCPv2Connection c : connections.values()){ - if (c.isConnected()){ - c.close(); - LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); - } + c.close(); + LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); connections.remove(c.getConnectionId()); } } diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index f3ca7312d..ea21da39d 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -33,17 +33,17 @@ public void init(IDSCPv2Settings settings){ @Override public void newConnectionHandler(IDSCPv2Connection connection) { this.connections.put(connection.getConnectionId(), connection); - System.out.println("New connection with id " + connection.getConnectionId()); + System.out.println("User: New connection with id " + connection.getConnectionId()); } @Override public void errorHandler(String error) { - System.out.println("Error occurred: " + error); + System.out.println("User: Error occurred: " + error); } @Override public void connectionClosedHandler(String connectionId) { - System.out.println("Connection closed"); + System.out.println("User: Connection closed"); connections.remove(connectionId); } } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index f326530b3..51aeee7c3 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -37,7 +37,7 @@ public void init(IDSCPv2Settings serverSettings) { } //secureServer.safeStop(); try { - Thread.sleep(120000); //run server for 2 minutes + Thread.sleep(20000); //run server for 2 minutes } catch (Exception e){ return; } @@ -46,16 +46,16 @@ public void init(IDSCPv2Settings serverSettings) { @Override public void newConnectionHandler(IDSCPv2Connection connection) { - System.out.println("New connection with id " + connection.getConnectionId()); + System.out.println("User: New connection with id " + connection.getConnectionId()); } @Override public void errorHandler(String error) { - System.out.println("Error occurred: " + error); + System.out.println("User: Error occurred: " + error); } @Override public void connectionClosedHandler(String connectionId) { - System.out.println("Connection with id " + connectionId + " has been closed"); + System.out.println("User: Connection with id " + connectionId + " has been closed"); } } diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java index 0be272085..2381d1071 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/test/java/RunTLSClient.java @@ -13,6 +13,5 @@ public static void main(String[] args){ IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); initiator.init(settings); - } } From aa1c17594d92c83886dedc412af90053ec83e819 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Thu, 6 Feb 2020 15:47:10 +0100 Subject: [PATCH 050/237] FSM simplify handshakeComplete --- .../daps/DefaultDapsDriver.java | 2 +- .../idscp_core/finite_state_machine/FSM.java | 129 +++++------------- .../finite_state_machine/State.java | 10 +- .../src/test/java/IDSCPv2ServerInitiator.java | 2 +- 4 files changed, 35 insertions(+), 108 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 35c229631..9d388668d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -16,6 +16,6 @@ public byte[] getToken() { @Override public int verifyToken(byte[] dat) { - return 3600; + return 20; } //returns number of seconds until dat is valid } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 03e8e5404..de8a855b5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -60,7 +60,7 @@ public class FSM implements FsmListener{ private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private int ratTimeoutDelay = 10; + private int ratTimeoutDelay = 120; public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ @@ -70,28 +70,19 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ /* ------------- Timeout Handler Routines ------------*/ - Runnable handshakeTimeoutHandler = new Runnable() { - @Override - public void run() { - System.out.println("HANDSHAKE_TIMER_EXPIRED"); - onControlMessage(InternalControlMessage.TIMEOUT); - } + Runnable handshakeTimeoutHandler = () -> { + System.out.println("HANDSHAKE_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.TIMEOUT); }; - Runnable datTimeoutHandler = new Runnable() { - @Override - public void run() { - System.out.println("DAT_TIMER_EXPIRED"); - onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); - } + Runnable datTimeoutHandler = () -> { + System.out.println("DAT_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); }; - Runnable ratTimeoutHandler = new Runnable() { - @Override - public void run() { - System.out.println("RAT_TIMER_EXPIRED"); - onControlMessage(InternalControlMessage.REPEAT_RAT); - } + Runnable ratTimeoutHandler = () -> { + System.out.println("RAT_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.REPEAT_RAT); }; //toDo set correct delays this.handshakeTimer = new Timer(fsmIsBusy, handshakeTimeoutHandler); @@ -149,7 +140,6 @@ public void run() { handshakeTimer.cancelTimeout(); LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -160,7 +150,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -170,7 +159,6 @@ public void run() { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -180,7 +168,6 @@ public void run() { handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -199,7 +186,6 @@ public void run() { sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } @@ -210,7 +196,6 @@ public void run() { sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } @@ -223,7 +208,6 @@ public void run() { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -273,7 +257,6 @@ public void run() { event -> { LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -283,7 +266,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -311,7 +293,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -322,7 +303,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -362,7 +342,6 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -401,7 +380,6 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -435,7 +413,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -444,7 +421,6 @@ public void run() { event -> { LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -454,7 +430,6 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -478,7 +453,6 @@ public void run() { LOG.debug("Start RAT Timer"); this.ratTimer.resetTimeout(ratTimeoutDelay); LOG.debug("Switch to state STATE_ESTABLISHED"); - connectionEstablished(); return STATE_ESTABLISHED; } )); @@ -489,7 +463,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -507,7 +480,6 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -573,8 +545,6 @@ public void run() { event -> { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -583,7 +553,6 @@ public void run() { event -> { LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -593,7 +562,6 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -615,7 +583,6 @@ public void run() { LOG.debug("Received RAT_PROVER OK"); this.handshakeTimer.cancelTimeout(); LOG.debug("Switch to state STATE_ESTABLISHED"); - connectionEstablished(); return STATE_ESTABLISHED; } )); @@ -626,7 +593,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -657,7 +623,6 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -718,7 +683,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -727,7 +691,6 @@ public void run() { event -> { LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -737,7 +700,6 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -746,7 +708,6 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -762,7 +723,6 @@ public void run() { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -832,7 +792,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -841,7 +800,6 @@ public void run() { event -> { LOG.debug("An internal control error occurred"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -851,7 +809,6 @@ public void run() { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -871,7 +828,6 @@ public void run() { LOG.debug("Send IDSC_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -889,7 +845,6 @@ public void run() { event -> { LOG.debug("Received IDSCP_CLOSE"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -905,7 +860,6 @@ public void run() { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } this.remoteDat = dat; @@ -976,7 +930,6 @@ public void run() { event -> { LOG.debug("Error occurred, close idscp connection"); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -986,7 +939,6 @@ public void run() { LOG.debug("Send IDSCP_CLOSE"); sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); LOG.debug("Switch to state STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -1062,7 +1014,6 @@ public void run() { event -> { LOG.debug("Receive IDSCP_CLOSED"); LOG.debug("Switch to STATE_CLOSED"); - connectionClosed(); return STATE_CLOSED; } )); @@ -1166,25 +1117,40 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMes } } - private void feedEvent(Event e){ + private void feedEvent(Event event){ State prevState = currentState; - currentState = currentState.feedEvent(e); - if (!prevState.equals(STATE_CLOSED) && currentState.equals(STATE_CLOSED)){ + currentState = currentState.feedEvent(event); + + //check if fsm switched to STATE_CLOSED + if (!prevState.equals(STATE_CLOSED) && currentState.equals(STATE_CLOSED)) { //fsm is closed, stop and free all resources, drivers and lock fsm forever secureChannel.close(); dapsDriver = null; - this.datTimer.cancelTimeout(); this.datTimer = null; this.ratTimer.cancelTimeout(); this.ratTimer = null; this.handshakeTimer.cancelTimeout(); this.handshakeTimer = null; - this.stopRatProverDriver(); this.stopRatVerifierDriver(); - fsmIsClosed = true; + + //inform upper layer via handshake or closeListener + try { + if (handshakeResultAvailable){ + listenerLatch.await(); + listener.onClose(); + } else { + notifyHandshakeCompleteLock(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + } else if (!prevState.equals(STATE_ESTABLISHED) && currentState.equals(STATE_ESTABLISHED) + && !handshakeResultAvailable) { + notifyHandshakeCompleteLock(); } } @@ -1241,39 +1207,6 @@ public void onClose(){ onControlMessage(InternalControlMessage.ERROR); } - private void connectionEstablished(){ - fsmIsBusy.lock(); - try { - if (!handshakeResultAvailable) { - notifyHandshakeCompleteLock(); - } - } finally { - fsmIsBusy.unlock(); - } - } - - private void connectionClosed(){ - fsmIsBusy.lock(); - try { - if (handshakeResultAvailable){ - listenerLatch.await(); - listener.onClose(); - } else { - notifyHandshakeCompleteLock(); - } - //terminate timeouts, rat drivers - this.handshakeTimer.cancelTimeout(); - this.datTimer.cancelTimeout(); - this.ratTimer.cancelTimeout(); - stopRatVerifierDriver(); - stopRatProverDriver(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - fsmIsBusy.unlock(); - } - } - public void send(IdscpMessage msg){ //send messages from user only when idscp connection is established fsmIsBusy.lock(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 92ea6cce6..551079fed 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -30,14 +30,8 @@ void addTransition(Object k, Transition t){ void setNoTransitionHandler(Function noTransitionHandler) { this.noTransitionHandler = noTransitionHandler; } -/* - protected void runEntryCode(){ - } - - protected void runExitCode(){ + public void runEntryCode() {} - } - - */ + public void runExitCode() {} } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 51aeee7c3..cedc582af 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -37,7 +37,7 @@ public void init(IDSCPv2Settings serverSettings) { } //secureServer.safeStop(); try { - Thread.sleep(20000); //run server for 2 minutes + Thread.sleep(120000); //run server for 2 minutes } catch (Exception e){ return; } From b00021bbc02cb26c1c383cb144b2d063b3355cc4 Mon Sep 17 00:00:00 2001 From: Leon Beckmann Date: Mon, 24 Feb 2020 16:54:06 +0100 Subject: [PATCH 051/237] FSM create classes for different states --- .../configuration/AttestationConfig.java | 4 + .../configuration/IDSCPv2Configuration.java | 12 +- .../configuration/IDSCPv2Settings.java | 6 +- .../idscp_core/finite_state_machine/FSM.java | 1101 ++--------------- .../finite_state_machine/State.java | 3 +- .../finite_state_machine/StateClosed.java | 68 + .../StateEstablished.java | 120 ++ .../StateWaitForDatAndRat.java | 156 +++ .../StateWaitForDatAndRatVerifier.java | 120 ++ .../StateWaitForHello.java | 138 +++ .../finite_state_machine/StateWaitForRat.java | 176 +++ .../StateWaitForRatProver.java | 151 +++ .../StateWaitForRatVerifier.java | 140 +++ .../States/StateClosed.java | 15 - .../States/StateEstablished.java | 6 - .../States/StateWaitForDatAndRat.java | 6 - .../States/StateWaitForDatAndRatVerifier.java | 6 - .../States/StateWaitForHello.java | 6 - .../States/StateWaitForRat.java | 6 - .../States/StateWaitForRatProver.java | 6 - .../States/StateWaitForRatVerifier.java | 6 - .../src/test/java/IDSCPv2ClientInitiator.java | 2 +- .../src/test/java/IDSCPv2ServerInitiator.java | 3 +- 23 files changed, 1193 insertions(+), 1064 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index 5a05122da..42beafbbe 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -11,4 +11,8 @@ public AttestationConfig(){ } + public String[] getRatMechanisms(){ + return new String[] {"TPM_2", "INTEL_SGX", "ARM_TRUST_ZONE"}; + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index d6c284c6f..a93cbed43 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -31,14 +31,20 @@ public class IDSCPv2Configuration implements IDSCPv2Callback { private IDSCPv2Initiator user; private DapsDriver dapsDriver; private SecureChannelDriver secureChannelDriver; + private final String[] localExpectedRatCipher; + private final String[] localSupportedRatCipher; public IDSCPv2Configuration(IDSCPv2Initiator initiator, DapsDriver dapsDriver, - SecureChannelDriver secureChannelDriver){ + SecureChannelDriver secureChannelDriver, + AttestationConfig expectedAttestation, + AttestationConfig supportedAttestation){ this.user = initiator; this.dapsDriver = dapsDriver; this.secureChannelDriver = secureChannelDriver; + this.localExpectedRatCipher = expectedAttestation.getRatMechanisms(); + this.localSupportedRatCipher = supportedAttestation.getRatMechanisms(); } public void connect(IDSCPv2Settings settings){ @@ -67,7 +73,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver); + FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, localExpectedRatCipher); try { fsm.startIdscpHandshake(); //blocking until handshake is done @@ -87,7 +93,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver); + FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, localExpectedRatCipher); try { fsm.startIdscpHandshake(); //blocking until handshake is done diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index 749281acf..c77d56a9b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -1,5 +1,7 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; +import org.checkerframework.checker.units.qual.A; + /** * IDSCPv2 configuration class, containing information about keyStore and TrustStores, Attestation Types, host, ... * @@ -16,8 +18,8 @@ public class IDSCPv2Settings { private String keyStorePassword = "password"; private String certAlias = "1.0.1"; private String keyStoreKeyType = "RSA"; - private AttestationConfig supportedAttestation = null; - private AttestationConfig expectedAttestation = null; + private AttestationConfig supportedAttestation = new AttestationConfig(); + private AttestationConfig expectedAttestation = new AttestationConfig(); public AttestationConfig getExpectedAttestation() { return expectedAttestation; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index de8a855b5..f0f988e60 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -13,6 +13,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -21,21 +22,23 @@ public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); /* ----------- IDSCPv2 Protocol States ---------- */ - private final State STATE_CLOSED = new State(); - private final State STATE_WAIT_FOR_HELLO = new State(); - private final State STATE_WAIT_FOR_RAT= new State(); - private final State STATE_WAIT_FOR_RAT_VERIFIER = new State(); - private final State STATE_WAIT_FOR_RAT_PROVER = new State(); - private final State STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER = new State(); - private final State STATE_WAIT_FOR_DAT_AND_RAT = new State(); - private final State STATE_ESTABLISHED = new State(); + private HashMap states = new HashMap<>(); + + enum FSM_STATE { + STATE_CLOSED, + STATE_WAIT_FOR_HELLO, + STATE_WAIT_FOR_RAT, + STATE_WAIT_FOR_RAT_VERIFIER, + STATE_WAIT_FOR_RAT_PROVER, + STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, + STATE_WAIT_FOR_DAT_AND_RAT, + STATE_ESTABLISHED + } private State currentState; - private final State initialState = STATE_CLOSED; /* ---------------- end of states --------------- */ private SecureChannel secureChannel; - private DapsDriver dapsDriver; private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; @@ -52,983 +55,59 @@ public class FSM implements FsmListener{ private boolean handshakeResultAvailable = false; private boolean fsmIsClosed = false; - //toDo cipher suites - private String[] localSupportedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; - private String[] localExpectedRatSuite = new String[] {"TPM_2, TRUST_ZONE, SGX"}; - private byte[] remoteDat = null; - private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private int ratTimeoutDelay = 120; + private final int ratTimeoutDelay = 120; - public FSM(SecureChannel secureChannel, DapsDriver dapsDriver){ + public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, + String[] localSupportedRatSuite, String[] localExpectedRatSuite){ this.secureChannel = secureChannel; - this.dapsDriver = dapsDriver; secureChannel.setFsm(this); /* ------------- Timeout Handler Routines ------------*/ Runnable handshakeTimeoutHandler = () -> { - System.out.println("HANDSHAKE_TIMER_EXPIRED"); + LOG.debug("HANDSHAKE_TIMER_EXPIRED"); onControlMessage(InternalControlMessage.TIMEOUT); }; Runnable datTimeoutHandler = () -> { - System.out.println("DAT_TIMER_EXPIRED"); + LOG.debug("DAT_TIMER_EXPIRED"); onControlMessage(InternalControlMessage.DAT_TIMER_EXPIRED); }; Runnable ratTimeoutHandler = () -> { - System.out.println("RAT_TIMER_EXPIRED"); + LOG.debug("RAT_TIMER_EXPIRED"); onControlMessage(InternalControlMessage.REPEAT_RAT); }; + //toDo set correct delays this.handshakeTimer = new Timer(fsmIsBusy, handshakeTimeoutHandler); this.datTimer = new Timer(fsmIsBusy, datTimeoutHandler); this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); /* ------------- end timeout routines ------------- */ - /* ----------- Protocol Transitions ---------- */ - - /*--------------------------------------------------- - * STATE_CLOSED - Transition Description - * --------------------------------------------------- - * onICM: start_handshake --> {send IDSCP_HELLO, set handshake_timeout} --> STATE_WAIT_FOR_HELLO - * ALL_OTHER_MESSAGES ---> STATE_CLOSED - * --------------------------------------------------- */ - STATE_CLOSED.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( - event -> { - LOG.debug("Get DAT Token vom DAT_DRIVER"); - byte[] dat = this.dapsDriver.getToken(); - LOG.debug("Send IDSCP_HELLO"); - IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. - getIdscpHelloMessage(dat, this.localSupportedRatSuite, this.localExpectedRatSuite); - sendFromFSM(idscpHello); - onMessageBlock.signalAll(); //enables fsm.onMessage() - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_HELLO"); - return STATE_WAIT_FOR_HELLO; - } - )); - - STATE_CLOSED.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_CLOSED"); - return STATE_CLOSED; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_HELLO - Transition Description - * --------------------------------------------------- - * onICM: error --> {} ---> STATE_CLOSED - * onICM: stop --> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_CLOSE---> {} ---> STATE_CLOSED - * onMessage: IDSCP_HELLO (no rat match) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_HELLO (invalid DAT) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_HELLO (SUCCESS) ---> {verify DAT, match RAT, set DAT Timeout, start RAT P&V, - * set handshake_timeout} ---> STATE_WAIT_FOR_RAT - * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_HELLO - * --------------------------------------------------- */ - STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - handshakeTimer.cancelTimeout(); - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - handshakeTimer.cancelTimeout(); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_HELLO.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - handshakeTimer.cancelTimeout(); - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_HELLO.addTransition(IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( - event -> { - handshakeTimer.cancelTimeout(); - LOG.debug("Received IDSCP_HELLO"); - IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); - - LOG.debug("Calculate Rat mechanisms"); - this.proverMechanism = getRatProverMechanism(this.localSupportedRatSuite, - idscpHello.getExpectedRatSuiteList().toArray()); - if (proverMechanism == null){ - LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", - IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - - this.verifierMechanism = getRatVerifierMechanism(localExpectedRatSuite, - idscpHello.getSupportedRatSuiteList().toArray()); - if (verifierMechanism == null){ - LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", - IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - - LOG.debug("Verify received DAT"); - //check if Dat is available and verify dat - byte[] dat; - int datValidityPeriod; - if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod= this.dapsDriver - .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray()))){ - LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - this.remoteDat = dat; - LOG.debug("Remote DAT is valid. Set dat timeout to its validity period"); - datTimer.resetTimeout(datValidityPeriod); - - LOG.debug("Start RAT Prover and Verifier"); - restartRatVerifierDriver(); - restartRatProverDriver(); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_HELLO.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_HELLO"); - return STATE_WAIT_FOR_HELLO; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_RAT - Transition Description - * --------------------------------------------------- - * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED - * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED - * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER - * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_WAIT_FOR_RAT_PROVER - * onICM: rat_prover_failed ---> {ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: rat_verifier_failed ---> {ratP.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT - * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT - * onICM: dat_timeout ---> {send DAT_EXPIRED, ratV.cancel()} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onICM: handshake_timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_RAT_PROVER ---> {delegate to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_DAT_EXPIRED ---> {send DAT, ratP.restart()} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_CLOSE ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED - * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT - * --------------------------------------------------- */ - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( - event -> { - LOG.debug("Received RAT_PROVER OK"); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( - event -> { - LOG.debug("Received RAT_VERIFIER OK"); - ratTimer.resetTimeout(this.ratTimeoutDelay); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( - event -> { - LOG.error("RAT_PROVER failed"); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( - event -> { - LOG.error("RAT_VERIFIER failed"); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_RAT_PROVER"); - sendFromFSM(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_RAT_VERIFIER"); - sendFromFSM(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( - event -> { - LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); - stopRatVerifierDriver(); - sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - ratProverDriver.delegate(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - ratVerifierDriver.delegate(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_RAT_VERIFIER - Transition Description - * --------------------------------------------------- - * onICM: error ---> {stop RAT_VERIFIER} ---> STATE_CLOSED - * onICM: close ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED - * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, cancel ratV} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED - * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_ESTABLISHED - * onICM: rat_verifier_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER - * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_CLOSE ---> {stop RAT_VERIFIER} ---> STATE_CLOSED - * onMessage: IDSCP_RAT_PROVER ---> {delegat to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER - * onMessage: IDSCP_RE_RAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT - * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER - * --------------------------------------------------- */ - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( - event -> { - LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); - stopRatVerifierDriver(); - sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); - return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( - event -> { - LOG.debug("Received RAT_VERIFIER OK"); - this.handshakeTimer.cancelTimeout(); - LOG.debug("Start RAT Timer"); - this.ratTimer.resetTimeout(ratTimeoutDelay); - LOG.debug("Switch to state STATE_ESTABLISHED"); - return STATE_ESTABLISHED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( - event -> { - LOG.error("RAT_VERIFIER failed"); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_RAT_VERIFIER"); - sendFromFSM(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - ratVerifierDriver.delegate(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); + states.put(FSM_STATE.STATE_CLOSED, new StateClosed(this, dapsDriver, onMessageBlock, + localSupportedRatSuite, localExpectedRatSuite)); + states.put(FSM_STATE.STATE_WAIT_FOR_HELLO, new StateWaitForHello(this, + handshakeTimer, datTimer, dapsDriver, localSupportedRatSuite, localExpectedRatSuite)); + states.put(FSM_STATE.STATE_WAIT_FOR_RAT, new StateWaitForRat(this, handshakeTimer, ratTimer, + ratTimeoutDelay, dapsDriver)); + states.put(FSM_STATE.STATE_WAIT_FOR_RAT_PROVER, new StateWaitForRatProver(this, ratTimer, handshakeTimer, + dapsDriver)); + states.put(FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER, new StateWaitForRatVerifier(this, dapsDriver, ratTimer, + handshakeTimer, ratTimeoutDelay)); + states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT, new StateWaitForDatAndRat(this, handshakeTimer, + datTimer, dapsDriver)); + states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, new StateWaitForDatAndRatVerifier(this, + handshakeTimer, datTimer, dapsDriver)); + states.put(FSM_STATE.STATE_ESTABLISHED, new StateEstablished(this, dapsDriver, ratTimer, handshakeTimer)); - STATE_WAIT_FOR_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT_VERIFIER.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_RAT_PROVER - Transition Description - * --------------------------------------------------- - * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER, timeouts.terminate()} ---> STATE_CLOSED - * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED - * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED - * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onICM: rat_prover_ok ---> {} ---> STATE_ESTABLISHED - * onICM: rat_prover_failed ---> {send IDSCP_CLOSE, terminate ratP, cancel timeouts} ---> STATE_CLOSED - * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onICM: repeat_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED - * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_PROVER - * --------------------------------------------------- */ - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( - event -> { - LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); - this.ratTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( - event -> { - LOG.debug("Received RAT_PROVER OK"); - this.handshakeTimer.cancelTimeout(); - LOG.debug("Switch to state STATE_ESTABLISHED"); - return STATE_ESTABLISHED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( - event -> { - LOG.error("RAT_PROVER failed"); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_RAT_PROVER"); - sendFromFSM(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( - event -> { - LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); - sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); - this.ratTimer.cancelTimeout(); - restartRatVerifierDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - ratProverDriver.delegate(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - restartRatProverDriver(); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_WAIT_FOR_RAT_PROVER.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description - * --------------------------------------------------- - * onICM: stop ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: error ---> {} ---> STATE_CLOSED - * onICM: timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED - * onMessage: IDSCP_DAT(success) --> {verify DAT, set det_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFEIER - * onMessage: IDSCP_DAT(failed) --> {verify DAT, send IDSCP_CLOSE} ---> STATE_CLOSED - * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onMessage: IDSCP_RE_RAT ---> {start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - * --------------------------------------------------- */ - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( - event -> { - this.handshakeTimer.cancelTimeout(); - LOG.debug("Verify received DAT"); - //check if Dat is available and verify dat - byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - int datValidityPeriod; - if (0 > (datValidityPeriod = this.dapsDriver.verifyToken(dat))){ - LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - this.remoteDat = dat; - LOG.debug("Remote DAT is valid. Set dat timeout"); - datTimer.resetTimeout(datValidityPeriod); - //start RAT Verifier - restartRatVerifierDriver(); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - restartRatProverDriver(); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); - return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; - } - ); - - /*--------------------------------------------------- - * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description - * --------------------------------------------------- - * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED - * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED - * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED - * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onMessage: IDSCP_CLOSE ---> {ratP.stop(), timeouts.stop()} ---> STATE_CLOSED - * onMessage: IDSCP_DAT(success) ---> {verify dat, start dat_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT - * onMessage: IDSCP_DAT(failed) ---> {verify dat, send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED - * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT - * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED - * --------------------------------------------------- */ - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("An internal control error occurred"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( - event -> { - LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IdscpClose.CloseCause.TIMEOUT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( - event -> { - LOG.debug("Received RAT_PROVER OK"); - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); - //toDo restart handshake timeout ???? - return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( - event -> { - LOG.error("RAT_PROVER failed"); - LOG.debug("Send IDSC_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", IdscpClose.CloseCause.RAT_PROVER_FAILED)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_RAT_PROVER"); - sendFromFSM(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_CLOSE"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( - event -> { - handshakeTimer.cancelTimeout(); - LOG.debug("Verify received DAT"); - //check if Dat is available and verify dat - byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - int datValidityPeriod; - if (0 > (datValidityPeriod = this.dapsDriver.verifyToken(dat))){ - LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IdscpClose.CloseCause.NO_VALID_DAT)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - this.remoteDat = dat; - LOG.debug("Remote DAT is valid. Set dat timeout"); - datTimer.resetTimeout(datValidityPeriod); - //start RAT Verifier - restartRatVerifierDriver(); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - return STATE_WAIT_FOR_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - ratProverDriver.delegate(event.getIdscpMessage()); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - restartRatProverDriver(); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - )); - - STATE_WAIT_FOR_DAT_AND_RAT.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_WAIT_FOR_DAT_AND_RAT"); - return STATE_WAIT_FOR_DAT_AND_RAT; - } - ); - - /*--------------------------------------------------- - * STATE_ESTABLISHED - Transition Description - * --------------------------------------------------- - * onICM: error ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED - * onICM: stop ---> {timeouts.cancel()} ---> STATE_CLOSED - * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER - * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED - * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED - * onMessage: IDSCP_RERAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER - * onMessage: IDSCP_CLOSE ---> {timeouts.cancel()} ---> STATE_CLOSED - * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED - * --------------------------------------------------- */ - STATE_ESTABLISHED.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { - LOG.debug("Error occurred, close idscp connection"); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_ESTABLISHED.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( - event -> { - LOG.debug("Send IDSCP_CLOSE"); - sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IdscpClose.CloseCause.USER_SHUTDOWN)); - LOG.debug("Switch to state STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_ESTABLISHED.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( - event -> { - LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); - this.ratTimer.cancelTimeout(); - sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); - restartRatVerifierDriver(); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_VERIFIER"); - return STATE_WAIT_FOR_RAT_VERIFIER; - } - )); - - STATE_ESTABLISHED.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( - event -> { - this.ratTimer.cancelTimeout(); - LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); - sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_DAT_AND_RAT_CLIENT"); - return STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER; - } - )); - - STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); - restartRatProverDriver(); - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("DAT expired. Send new DAT and repeat RAT"); - sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(this.dapsDriver.getToken())); - restartRatProverDriver(); - - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - - LOG.debug("Switch to state STATE_WAIT_FOR_RAT_PROVER"); - return STATE_WAIT_FOR_RAT_PROVER; - } - )); - - STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( - event -> { - try { - this.listenerLatch.await(); - this.listener.onMessage(event.getIdscpMessage().getIdscpData().toByteArray()); - LOG.debug("Idscp data was passed to connection listener"); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - - LOG.debug("Stay in state STATE_ESTABLISHED"); - return STATE_ESTABLISHED; - } - )); - - STATE_ESTABLISHED.addTransition(IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( - event -> { - LOG.debug("Receive IDSCP_CLOSED"); - LOG.debug("Switch to STATE_CLOSED"); - return STATE_CLOSED; - } - )); - - STATE_ESTABLISHED.setNoTransitionHandler( - event -> { - LOG.debug("No transition available for given event " + event.toString()); - LOG.debug("Stay in state STATE_ESTABLISHED"); - return STATE_ESTABLISHED; - } - ); - /* ---------------- end of transitions --------------- */ //set initial state - currentState = initialState; + currentState = states.get(FSM_STATE.STATE_CLOSED); } @Override @@ -1046,7 +125,7 @@ public void onMessage(byte[] data){ //must wait when fsm is in state STATE_CLOSED --> wait() will be notified when fsm is leaving STATE_CLOSED fsmIsBusy.lock(); try { - while (currentState == STATE_CLOSED){ + while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))){ try { onMessageBlock.await(); } catch (InterruptedException e) { @@ -1121,36 +200,8 @@ private void feedEvent(Event event){ State prevState = currentState; currentState = currentState.feedEvent(event); - //check if fsm switched to STATE_CLOSED - if (!prevState.equals(STATE_CLOSED) && currentState.equals(STATE_CLOSED)) { - //fsm is closed, stop and free all resources, drivers and lock fsm forever - secureChannel.close(); - dapsDriver = null; - this.datTimer.cancelTimeout(); - this.datTimer = null; - this.ratTimer.cancelTimeout(); - this.ratTimer = null; - this.handshakeTimer.cancelTimeout(); - this.handshakeTimer = null; - this.stopRatProverDriver(); - this.stopRatVerifierDriver(); - fsmIsClosed = true; - - //inform upper layer via handshake or closeListener - try { - if (handshakeResultAvailable){ - listenerLatch.await(); - listener.onClose(); - } else { - notifyHandshakeCompleteLock(); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - } else if (!prevState.equals(STATE_ESTABLISHED) && currentState.equals(STATE_ESTABLISHED) - && !handshakeResultAvailable) { - notifyHandshakeCompleteLock(); + if (!prevState.equals(currentState)) { + currentState.runEntryCode(this); } } @@ -1164,7 +215,7 @@ public void terminate(){ public void startIdscpHandshake() throws IDSCPv2Exception { fsmIsBusy.lock(); try { - if (currentState.equals(STATE_CLOSED)) { + if (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { if (fsmIsClosed) { throw new IDSCPv2Exception("FSM is in a final closed state forever"); } @@ -1192,7 +243,7 @@ public void startIdscpHandshake() throws IDSCPv2Exception { } } - private void sendFromFSM(IdscpMessage msg){ + void sendFromFSM(IdscpMessage msg){ //send messages from fsm secureChannel.send(msg.toByteArray()); } @@ -1222,7 +273,7 @@ public void send(IdscpMessage msg){ } public boolean isConnected(){ - return currentState.equals(STATE_ESTABLISHED); + return currentState.equals(states.get(FSM_STATE.STATE_ESTABLISHED)); } public void registerMessageListener(IdscpMsgListener listener){ @@ -1230,7 +281,7 @@ public void registerMessageListener(IdscpMsgListener listener){ listenerLatch.countDown(); } - private void notifyHandshakeCompleteLock(){ + void notifyHandshakeCompleteLock(){ fsmIsBusy.lock(); try { handshakeResultAvailable = true; @@ -1241,18 +292,18 @@ private void notifyHandshakeCompleteLock(){ } //calculate Prover mechanism (strongest remote expected), returns null if no match was found - private String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ + String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ //toDo implement logic return "TPM_2"; } //calculate Verifier mechanism (strongest local expected), returns null if no match was found - private String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ + String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ //toDo implement logic return "TPM_2"; } - private void restartRatVerifierDriver(){ + void restartRatVerifierDriver(){ //assume verifier mechanism is set stopRatVerifierDriver(); ratVerifierDriver = RatVerifierDriverRegistry.startRatVerifierDriver(verifierMechanism, this); @@ -1265,14 +316,14 @@ private void restartRatVerifierDriver(){ } } - private void stopRatVerifierDriver(){ + void stopRatVerifierDriver(){ if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ ratVerifierDriver.interrupt(); ratVerifierDriver.terminate(); } } - private void restartRatProverDriver(){ + void restartRatProverDriver(){ //assume prover mechanism is set stopRatProverDriver(); ratProverDriver = RatProverDriverRegistry.startRatProverDriver(proverMechanism, this); @@ -1285,10 +336,64 @@ private void restartRatProverDriver(){ } } - private void stopRatProverDriver(){ + void stopRatProverDriver(){ if (ratProverDriver != null && ratProverDriver.isAlive()){ ratProverDriver.interrupt(); ratProverDriver.terminate(); } } + + void setRatMechanisms(String proverMechanism, String verifierMechanism) { + this.proverMechanism = proverMechanism; + this.verifierMechanism = verifierMechanism; + } + + + + State getState(FSM_STATE state){ + return states.get(state); + } + + void lockFsm(){ + secureChannel.close(); + this.datTimer.cancelTimeout(); + this.datTimer = null; + this.ratTimer.cancelTimeout(); + this.ratTimer = null; + this.handshakeTimer.cancelTimeout(); + this.handshakeTimer = null; + this.stopRatProverDriver(); + this.stopRatVerifierDriver(); + fsmIsClosed = true; + + //inform upper layer via handshake or closeListener + try { + if (handshakeResultAvailable){ + listenerLatch.await(); + listener.onClose(); + } else { + notifyHandshakeCompleteLock(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + RatVerifierDriver getRatVerifierDriver() { + return ratVerifierDriver; + } + + RatProverDriver getRatProverDriver() { + return ratProverDriver; + } + + void notifyIdscpMsgListener(byte[] data) { + try { + this.listenerLatch.await(); + this.listener.onMessage(data); + LOG.debug("Idscp data were passed to connection listener"); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 551079fed..f3e534315 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -31,7 +31,6 @@ void setNoTransitionHandler(Function noTransitionHandler) { this.noTransitionHandler = noTransitionHandler; } - public void runEntryCode() {} + void runEntryCode(FSM fsm) {} - public void runExitCode() {} } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java new file mode 100644 index 000000000..2d553b8e0 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -0,0 +1,68 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.locks.Condition; + + +class StateClosed extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateClosed.class); + + public StateClosed(FSM fsm, + DapsDriver dapsDriver, + Condition onMessageLock, + String[] localSupportedRatSuite, + String[] localExpectedRatSuite){ + + + /*--------------------------------------------------- + * STATE_CLOSED - Transition Description + * --------------------------------------------------- + * onICM: start_handshake --> {send IDSCP_HELLO, set handshake_timeout} --> STATE_WAIT_FOR_HELLO + * ALL_OTHER_MESSAGES ---> STATE_CLOSED + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.START_IDSCP_HANDSHAKE.getValue(), new Transition( + event -> { + + LOG.debug("Get DAT Token vom DAT_DRIVER"); + byte[] dat = dapsDriver.getToken(); + + LOG.debug("Send IDSCP_HELLO"); + IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. + getIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); + fsm.sendFromFSM(idscpHello); + + runExitCode(onMessageLock); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_HELLO); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_CLOSED"); + return this; + } + ); + + } + + private void runExitCode(Condition onMessageLock){ + //State Closed exit code + onMessageLock.signalAll(); //enables fsm.onMessage() + } + + @Override + void runEntryCode(FSM fsm){ + //State Closed entry code + LOG.debug("Switched to state STATE_CLOSED"); + LOG.debug("Terminate and free all resources and lock fsm forever"); + fsm.lockFsm(); + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java new file mode 100644 index 000000000..bec092246 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -0,0 +1,120 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateEstablished extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateEstablished.class); + + public StateEstablished(FSM fsm, + DapsDriver dapsDriver, + Timer ratTimer, + Timer handshakeTimer) { + + + /*--------------------------------------------------- + * STATE_ESTABLISHED - Transition Description + * --------------------------------------------------- + * onICM: error ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: stop ---> {timeouts.cancel()} ---> STATE_CLOSED + * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED + * onMessage: IDSCP_RERAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_CLOSE ---> {timeouts.cancel()} ---> STATE_CLOSED + * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("Error occurred, close idscp connection"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( + event -> { + LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); + ratTimer.cancelTimeout(); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); + fsm.restartRatVerifierDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); + } + )); + + this.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + ratTimer.cancelTimeout(); + LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); + fsm.restartRatProverDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("DAT expired. Send new DAT and repeat RAT"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( + event -> { + fsm.notifyIdscpMsgListener(event.getIdscpMessage().getIdscpData().toByteArray()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Receive IDSCP_CLOSED"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_ESTABLISHED"); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switched to state STATE_ESTABLISHED"); + fsm.notifyHandshakeCompleteLock(); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java new file mode 100644 index 000000000..a01e931b9 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -0,0 +1,156 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForDatAndRat extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRat.class); + + private final Timer handshakeTimer; + + public StateWaitForDatAndRat(FSM fsm, + Timer handshakeTimer, + Timer datTimer, + DapsDriver dapsDriver + ){ + this.handshakeTimer = handshakeTimer; + + /*--------------------------------------------------- + * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description + * --------------------------------------------------- + * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onICM: rat_prover_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_CLOSE ---> {ratP.stop(), timeouts.stop()} ---> STATE_CLOSED + * onMessage: IDSCP_DAT(success) ---> {verify dat, start dat_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_DAT(failed) ---> {verify dat, send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_ESTABLISHED + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + fsm.sendFromFSM(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + event -> { + handshakeTimer.cancelTimeout(); + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); + int datValidityPeriod; + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat))){ + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + + LOG.debug("Remote DAT is valid. Set dat timeout"); + datTimer.resetTimeout(datValidityPeriod); + //start RAT Verifier + fsm.restartRatVerifierDriver(); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); + fsm.restartRatProverDriver(); + return this; + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT"); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java new file mode 100644 index 000000000..035987fc2 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -0,0 +1,120 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForDatAndRatVerifier extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRatVerifier.class); + + private final Timer handshakeTimer; + + public StateWaitForDatAndRatVerifier(FSM fsm, + Timer handshakeTimer, + Timer datTimer, + DapsDriver dapsDriver){ + + this.handshakeTimer = handshakeTimer; + /*--------------------------------------------------- + * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description + * --------------------------------------------------- + * onICM: stop ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: error ---> {} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * onMessage: IDSCP_DAT(success) --> {verify DAT, set det_timeout, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFEIER + * onMessage: IDSCP_DAT(failed) --> {verify DAT, send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onMessage: IDSCP_RE_RAT ---> {start IDSCP_PROVER} ---> STATE_WAIT_FOR_DAT_AND_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + event -> { + handshakeTimer.cancelTimeout(); + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); + int datValidityPeriod; + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat))){ + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + LOG.debug("Remote DAT is valid. Set dat timeout"); + datTimer.resetTimeout(datValidityPeriod); + //start RAT Verifier + fsm.restartRatVerifierDriver(); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); + fsm.restartRatProverDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java new file mode 100644 index 000000000..ddb7ea88c --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -0,0 +1,138 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForHello extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForHello.class); + + private final Timer handshakeTimer; + + public StateWaitForHello(FSM fsm, + Timer handshakeTimer, + Timer datTimer, + DapsDriver dapsDriver, + String[] localSupportedRatSuite, + String[] localExpectedRatSuite) { + + this.handshakeTimer = handshakeTimer; + + /*--------------------------------------------------- + * STATE_WAIT_FOR_HELLO - Transition Description + * --------------------------------------------------- + * onICM: error --> {} ---> STATE_CLOSED + * onICM: stop --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: timeout --> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_CLOSE---> {} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (no rat match) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (invalid DAT) ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_HELLO (SUCCESS) ---> {verify DAT, match RAT, set DAT Timeout, start RAT P&V, + * set handshake_timeout} ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_HELLO + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Received stop signal from user. Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", + IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( + event -> { + handshakeTimer.cancelTimeout(); + + LOG.debug("Received IDSCP_HELLO"); + IDSCPv2.IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); + + LOG.debug("Calculate Rat mechanisms"); + String proverMechanism = fsm.getRatProverMechanism(localSupportedRatSuite, + idscpHello.getExpectedRatSuiteList().toArray()); + if (proverMechanism == null){ + LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", + IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + + String verifierMechanism = fsm.getRatVerifierMechanism(localExpectedRatSuite, + idscpHello.getSupportedRatSuiteList().toArray()); + if (verifierMechanism == null){ + LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", + IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + + LOG.debug("Verify received DAT"); + //check if Dat is available and verify dat + byte[] dat; + int datValidityPeriod; + if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver + .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray()))){ + LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", + IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + + LOG.debug("Remote DAT is valid. Set dat timeout to its validity period"); + datTimer.resetTimeout(datValidityPeriod); + + fsm.setRatMechanisms(proverMechanism, verifierMechanism); + + LOG.debug("Start RAT Prover and Verifier"); + fsm.restartRatVerifierDriver(); + fsm.restartRatProverDriver(); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_HELLO"); + return this; + } + ); + } + + + @Override + void runEntryCode(FSM fsm) { + LOG.debug("Switched to state STATE_WAIT_FOR_HELLO"); + LOG.debug("Set handshake timeout to 5 seconds"); + handshakeTimer.resetTimeout(5); + } + + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java new file mode 100644 index 000000000..7cb3bb4e1 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -0,0 +1,176 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForRat extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRat.class); + + private final Timer handshakeTimer; + + public StateWaitForRat(FSM fsm, + Timer handshakeTimer, + Timer ratTimer, + int ratTimerDelay, + DapsDriver dapsDriver){ + + this.handshakeTimer = handshakeTimer; + + + /*--------------------------------------------------- + * STATE_WAIT_FOR_RAT - Transition Description + * --------------------------------------------------- + * onICM: error ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED + * onICM: stop ---> {ratP.stop(), ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> IDSCP_CLOSED + * onICM: rat_prover_ok ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_WAIT_FOR_RAT_PROVER + * onICM: rat_prover_failed ---> {ratV.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_verifier_failed ---> {ratP.stop(), timeouts.stop(), send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onICM: dat_timeout ---> {send DAT_EXPIRED, ratV.cancel()} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onICM: handshake_timeout ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_RAT_PROVER ---> {delegate to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_DAT_EXPIRED ---> {send DAT, ratP.restart()} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {ratP.stop(), ratV.stop(), timeouts.stop()} ---> IDSCP_CLOSED + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_VERIFIER OK"); + ratTimer.resetTimeout(ratTimerDelay); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_VERIFIER failed"); + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", + IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + fsm.sendFromFSM(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_VERIFIER"); + fsm.sendFromFSM(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); + fsm.stopRatVerifierDriver(); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); + fsm.getRatVerifierDriver().delegate(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT"); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java new file mode 100644 index 000000000..bad5b19a7 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -0,0 +1,151 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForRatProver extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRatProver.class); + + public StateWaitForRatProver(FSM fsm, + Timer ratTimer, + Timer handshakeTimer, + DapsDriver dapsDriver){ + + + /*--------------------------------------------------- + * STATE_WAIT_FOR_RAT_PROVER - Transition Description + * --------------------------------------------------- + * onICM: stop ---> {send IDSCP_CLOSE, stop RAT_PROVER, timeouts.terminate()} ---> STATE_CLOSED + * onICM: error ---> {stop RAT_PROVER} ---> STATE_CLOSED + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_PROVER} ---> STATE_CLOSED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT + * onICM: rat_prover_ok ---> {} ---> STATE_ESTABLISHED + * onICM: rat_prover_failed ---> {send IDSCP_CLOSE, terminate ratP, cancel timeouts} ---> STATE_CLOSED + * onICM: rat_prover_msg ---> {send IDSCP_RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onICM: repeat_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {} ---> STATE_CLOSED + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_RAT_VERIFIER ---> {delegate to RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * onMessage: IDSCP_RE_RAT ---> {restart RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_PROVER + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); + ratTimer.cancelTimeout(); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_PROVER OK"); + handshakeTimer.cancelTimeout(); + return fsm.getState(FSM.FSM_STATE.STATE_ESTABLISHED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_PROVER failed"); + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_PROVER"); + fsm.sendFromFSM(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( + event -> { + LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); + ratTimer.cancelTimeout(); + fsm.restartRatVerifierDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); + fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); + fsm.restartRatProverDriver(); + return this; + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_PROVER"); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switched to state STATE_WAIT_FOR_RAT_PROVER"); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java new file mode 100644 index 000000000..59c1ee108 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -0,0 +1,140 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StateWaitForRatVerifier extends State { + private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRatVerifier.class); + + public StateWaitForRatVerifier(FSM fsm, + DapsDriver dapsDriver, + Timer ratTimer, + Timer handshakeTimer, + int ratTimeoutDelay) { + + /*--------------------------------------------------- + * STATE_WAIT_FOR_RAT_VERIFIER - Transition Description + * --------------------------------------------------- + * onICM: error ---> {stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: close ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED, cancel ratV} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER + * onICM: timeout ---> {send IDSCP_CLOSE, stop RAT_VERIFIER} ---> STATE_CLOSED + * onICM: rat_verifier_ok ---> {set rat timeout} ---> STATE_ESTABLISHED + * onICM: rat_verifier_failed ---> {send IDSCP_CLOSE} ---> STATE_CLOSED + * onICM: rat_verifier_msg ---> {send IDSCP_RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onMessage: IDSCP_DAT_EXPIRED ---> {send IDSCP_DAT, start RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * onMessage: IDSCP_CLOSE ---> {stop RAT_VERIFIER} ---> STATE_CLOSED + * onMessage: IDSCP_RAT_PROVER ---> {delegat to RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER + * onMessage: IDSCP_RE_RAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT + * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT_VERIFIER + * --------------------------------------------------- */ + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( + event -> { + LOG.debug("An internal control error occurred"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( + event -> { + LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.DAT_TIMER_EXPIRED.getValue(), new Transition( + event -> { + LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); + fsm.stopRatVerifierDriver(); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( + event -> { + LOG.debug("Received RAT_VERIFIER OK"); + handshakeTimer.cancelTimeout(); + LOG.debug("Start RAT Timer"); + ratTimer.resetTimeout(ratTimeoutDelay); + return fsm.getState(FSM.FSM_STATE.STATE_ESTABLISHED); + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_FAILED.getValue(), new Transition( + event -> { + LOG.error("RAT_VERIFIER failed"); + LOG.debug("Send IDSC_CLOSE"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", + IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( + event -> { + LOG.debug("Send IDSCP_RAT_VERIFIER"); + fsm.sendFromFSM(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_CLOSE"); + return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); + fsm.restartRatProverDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); + fsm.getRatVerifierDriver().delegate(event.getIdscpMessage()); + return this; + } + )); + + this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + event -> { + LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); + fsm.restartRatProverDriver(); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); + } + )); + + this.setNoTransitionHandler( + event -> { + LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("Stay in state STATE_WAIT_FOR_RAT_VERIFIER"); + return this; + } + ); + } + + @Override + void runEntryCode(FSM fsm){ + LOG.debug("Switched to state STATE_WAIT_FOR_RAT_VERIFIER"); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java deleted file mode 100644 index 02f973e16..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateClosed.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - - - -public class StateClosed extends State { - - public StateClosed(FSM fsm){ - - } - -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java deleted file mode 100644 index 7180c462f..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateEstablished.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateEstablished extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java deleted file mode 100644 index f90e5b829..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRat.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForDatAndRat extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java deleted file mode 100644 index 9dd6a0c95..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForDatAndRatVerifier.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForDatAndRatVerifier extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java deleted file mode 100644 index dec7a21bf..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForHello.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForHello extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java deleted file mode 100644 index 790c69e77..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRat.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForRat extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java deleted file mode 100644 index 0c0f11ef2..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatProver.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForRatProver extends State { -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java deleted file mode 100644 index 842e056b5..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/States/StateWaitForRatVerifier.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.States; - -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.State; - -public class StateWaitForRatVerifier extends State { -} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index ea21da39d..cda0fa9e5 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -25,7 +25,7 @@ public void init(IDSCPv2Settings settings){ RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, - dapsDriver, secureChannelDriver); + dapsDriver, secureChannelDriver, settings.getExpectedAttestation(), settings.getSupportedAttestation()); clientConfig.connect(settings); } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index cedc582af..e81a21e1e 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -27,7 +27,8 @@ public void init(IDSCPv2Settings serverSettings) { RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, - dapsDriver, secureChannelDriver); + dapsDriver, secureChannelDriver, serverSettings.getExpectedAttestation(), + serverSettings.getSupportedAttestation()); IDSCPv2Server idscPv2Server; try { idscPv2Server = idscpServerConfig.listen(serverSettings); From e3283e29734861d7dc1259eba00a5f9da76f79c8 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Sat, 21 Mar 2020 21:12:10 +0100 Subject: [PATCH 052/237] WIP: Implement DefaultDapsDriver --- idscp2/build.gradle | 8 + .../daps/DefaultDapsDriver.java | 258 +++++++++++++++++- .../daps/DefaultDapsDriverConfig.java | 100 +++++++ .../daps/SecurityRequirements.java | 28 ++ .../CustomX509ExtendedKeyManager.java | 2 +- .../CustomX509ExtendedTrustManager.java | 2 +- .../PreConfiguration.java} | 42 ++- .../secure_channel/client/TLSClient.java | 8 +- .../secure_channel/server/TLSServer.java | 7 +- .../idscp2/drivers/interfaces/DapsDriver.java | 2 +- .../StateWaitForDatAndRat.java | 2 +- .../StateWaitForDatAndRatVerifier.java | 2 +- .../StateWaitForHello.java | 2 +- idscp2/src/test/java/DapsDriverTest.java | 7 + .../src/test/java/IDSCPv2ClientInitiator.java | 14 +- .../src/test/java/IDSCPv2ServerInitiator.java | 14 +- 16 files changed, 465 insertions(+), 33 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/{secure_channel => }/keystores/CustomX509ExtendedKeyManager.java (98%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/{secure_channel => }/keystores/CustomX509ExtendedTrustManager.java (97%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/{secure_channel/keystores/TLSPreConfiguration.java => keystores/PreConfiguration.java} (81%) create mode 100644 idscp2/src/test/java/DapsDriverTest.java diff --git a/idscp2/build.gradle b/idscp2/build.gradle index 4aee0a96c..e48f54184 100644 --- a/idscp2/build.gradle +++ b/idscp2/build.gradle @@ -21,6 +21,14 @@ dependencies { testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb + providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken + providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken + providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken + providedByBundle group: 'org.json', name: 'json', version: '20180813' + providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.6.5' + + providedByBundle group: 'com.squareup.okhttp3', name: 'okhttp', version: libraryVersions.okhttp + testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 9d388668d..c41ef33e7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -1,6 +1,40 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import java.io.IOException; +import java.security.Key; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.Date; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import okhttp3.FormBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.jose4j.http.Get; +import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; +import org.jose4j.jwk.HttpsJwks; +import org.jose4j.jws.AlgorithmIdentifiers; +import org.jose4j.jwt.JwtClaims; +import org.jose4j.jwt.consumer.InvalidJwtException; +import org.jose4j.jwt.consumer.JwtConsumer; +import org.jose4j.jwt.consumer.JwtConsumerBuilder; +import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + /** * Default DAPS Driver for requesting valid dynamicAttributeToken and verifying DAT @@ -8,14 +42,230 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class DefaultDapsDriver implements DapsDriver { + private static final Logger LOG = LoggerFactory.getLogger(DefaultDapsDriver.class); + + private SSLSocketFactory sslSocketFactory; + private X509ExtendedTrustManager trustManager; + private Key privateKey; + private String connectorUUID; + private String dapsUrl; + private String targetAudience = "IDS_Connector"; + + public DefaultDapsDriver(DefaultDapsDriverConfig config) { + + this.connectorUUID = config.getConnectorUUID(); + this.dapsUrl = config.getDapsUrl(); + + //create ssl context + privateKey = PreConfiguration.getKey( + config.getKeyStorePath(), + config.getKeyStorePassword(), + config.getKeyAlias() + ); + + TrustManager[] trustManagers = PreConfiguration.getX509ExtTrustManager( + config.getTrustStorePath(), + config.getTrustStorePassword() + ); + + this.trustManager = (X509ExtendedTrustManager) trustManagers[0]; + + try { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, null); + sslSocketFactory = sslContext.getSocketFactory(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + LOG.error("Cannot init DefaultDapsDriver: {}", e.toString()); + throw new RuntimeException(e); + } + } @Override public byte[] getToken() { - return new byte[0]; + String invalidToken = "INVALID_TOKEN"; + String token; + + LOG.info("Retrieving Dynamic Attribute Token..."); + + //create signed JWT + String jwt = + Jwts.builder() + .setIssuer(connectorUUID) + .setSubject(connectorUUID) + .setExpiration(Date.from(Instant.now().plusSeconds(86400))) + .setIssuedAt(Date.from(Instant.now())) + .setNotBefore(Date.from(Instant.now())) + .setAudience(targetAudience) + .signWith(privateKey, SignatureAlgorithm.RS256).compact(); + + //build http client and request for DAPS + RequestBody formBody = + new FormBody.Builder() + .add("grant_type", "client_credentials") + .add( + "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + .add("client_assertion", jwt) + .add("scope", "ids_connector") + .build(); + + OkHttpClient client = + new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, trustManager) + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .build(); + + Request request = + new Request.Builder() + .url(dapsUrl.concat("/token")) + .post(formBody) + .build(); + + try { + //get http response from DAPS + LOG.debug("Acquire DAT from {}", dapsUrl); + Response response = client.newCall(request).execute(); + + //check for valid response + if (!response.isSuccessful()) { + LOG.error("Get unsuccessful http response: {}", response.toString()); + return invalidToken.getBytes(); + } + + if (response.body() == null) { + LOG.error("Get empty DAPS response"); + return invalidToken.getBytes(); + } + + JSONObject json = new JSONObject(response.body().string()); + if (json.has("access_token")) { + token = json.getString("access_token"); + LOG.info("Get access_token from DAPS: {}", token); + } else if (json.has("error")) { + LOG.error("Get DAPS error response: {}", json.getString("error")); + return invalidToken.getBytes(); + } else { + LOG.error("Get unknown DAPS response format: {}", json.toString()); + return invalidToken.getBytes(); + } + + //verify token once without security attr validation before providing it + if (verifyToken(token.getBytes(), null) > 0) { + LOG.info("DAT is valid"); + return token.getBytes(); + } else { + LOG.error("DAT validation failed"); + return invalidToken.getBytes(); + } + } catch (IOException e) { + LOG.error("Cannot acquire DAT from DAPS: ", e); + return invalidToken.getBytes(); + } } @Override - public int verifyToken(byte[] dat) { - return 20; - } //returns number of seconds until dat is valid + public int verifyToken(byte[] dat, Object securityRequirements) { + + LOG.info("Verify dynamic attribute token ..."); + + // Get JsonWebKey JWK from JsonWebKeyStore JWKS using DAPS JWKS endpoint + HttpsJwks httpsJwks = new HttpsJwks(dapsUrl.concat("/.well-known/jwks.json")); + Get getInstance = new Get(); + getInstance.setSslSocketFactory(sslSocketFactory); + httpsJwks.setSimpleHttpGet(getInstance); + + // create new jwks key resolver, selects jwk based on key ID in jwt header + HttpsJwksVerificationKeyResolver jwksKeyResolver + = new HttpsJwksVerificationKeyResolver(httpsJwks); + + //create validation requirements + JwtConsumer jwtConsumer = + new JwtConsumerBuilder() + .setRequireExpirationTime() // has expiration time + .setAllowedClockSkewInSeconds(30) // leeway in validation time + .setRequireSubject() // has subject + .setExpectedAudience(targetAudience) + .setExpectedIssuer(dapsUrl) // e.g. https://daps.aisec.fraunhofer.de + .setVerificationKeyResolver(jwksKeyResolver) //get decryption key from jwks + .setJweAlgorithmConstraints( + new AlgorithmConstraints( + ConstraintType.WHITELIST, + AlgorithmIdentifiers.RSA_USING_SHA256 + ) + ) + .build(); + + //verify dat + JwtClaims claims; + + LOG.debug("Request JWKS from DAPS for validating DAT"); + + try { + claims = jwtConsumer.processToClaims(new String(dat)); + } catch (InvalidJwtException e) { + LOG.error("DAPS response is not a valid DAT format", e); + return -1; + } + + //check security requirements + if (securityRequirements != null) { + LOG.debug("Validate security attributes"); + + if (securityRequirements instanceof SecurityRequirements) { + SecurityRequirements secRequirements = (SecurityRequirements) securityRequirements; + SecurityRequirements providedSecurityProfile = + parseSecurityRequirements(claims.toJson()); + + if (providedSecurityProfile == null) { + return -1; + } + + //toDo add further security attribute validation + if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) + { + LOG.info("DAT is valid and secure"); + return 20; + } else { + LOG.warn("DAT does not fulfill the security requirements"); + return -1; + } + } else { + //invalid security requirements format + LOG.error("Invalid security requirements format. Expected SecurityRequirements.class"); + return -1; + } + } else { + LOG.info("DAT is valid"); + return 20; + } + } //returns number of seconds dat is valid + + private SecurityRequirements parseSecurityRequirements(String dynamicAttrToken) { + JSONObject asJson = new JSONObject(dynamicAttrToken); + + if (!asJson.has("ids_attributes")) { + LOG.error("DAT does not contain ids_attributes"); + return null; + } + JSONObject idsAttributes = asJson.getJSONObject("ids_attributes"); + + if (!idsAttributes.has("security_profile")) { + LOG.error("DAT does not contain security_profile"); + return null; + } + JSONObject securityProfile = idsAttributes.getJSONObject("security_profile"); + + //check if all security requirements are available + if (!securityProfile.has("audit_logging")) { + LOG.error("DAT does not contain audit_logging"); + return null; + } + + //toDo parse further security attributes + + return new SecurityRequirements.Builder() + .setAuditLogging(securityProfile.getInt("audit_logging")) + .build(); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java new file mode 100644 index 000000000..2979228a2 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java @@ -0,0 +1,100 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps; + +import org.checkerframework.checker.nullness.qual.NonNull; + +public class DefaultDapsDriverConfig { + + @NonNull private String dapsUrl = "https://daps.aisec.fraunhofer.de"; + @NonNull private String keyStorePath = ""; + @NonNull private String keyStorePassword = "password"; + @NonNull private String keyAlias = "1"; + @NonNull private String trustStorePath = ""; + @NonNull private String trustStorePassword = "password"; + @NonNull private String connectorUUID = ""; + + public static class Builder { + @NonNull private DefaultDapsDriverConfig config = new DefaultDapsDriverConfig(); + + @NonNull + public Builder setDapsUrl(String dapsUrl) { + this.config.dapsUrl = dapsUrl; + return this; + } + + @NonNull + public Builder setKeyStorePath(String path) { + this.config.keyStorePath = path; + return this; + } + + @NonNull + public Builder setKeyStorePassword(String password) { + this.config.keyStorePassword = password; + return this; + } + + @NonNull + public Builder setKeyAlias(String alias) { + this.config.keyAlias = alias; + return this; + } + + @NonNull + public Builder setTrustStorePath(String path) { + this.config.trustStorePath = path; + return this; + } + + @NonNull + public Builder setTrustStorePassword(String password) { + this.config.trustStorePassword = password; + return this; + } + + @NonNull + public Builder setConnectorUUID(String uuid) { + this.config.connectorUUID = uuid; + return this; + } + + @NonNull + public DefaultDapsDriverConfig build() { + return config; + } + } + + @NonNull + public String getDapsUrl() { + return dapsUrl; + } + + @NonNull + public String getKeyStorePath() { + return keyStorePath; + } + + @NonNull + public String getKeyStorePassword() { + return keyStorePassword; + } + + @NonNull + public String getKeyAlias() { + return keyAlias; + } + + @NonNull + public String getTrustStorePath() { + return trustStorePath; + } + + @NonNull + public String getTrustStorePassword() { + return trustStorePassword; + } + + @NonNull + public String getConnectorUUID() { + return connectorUUID; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java new file mode 100644 index 000000000..097bc2cb7 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -0,0 +1,28 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps; + + +import org.checkerframework.checker.nullness.qual.NonNull; + +public class SecurityRequirements { + + private int auditLogging; + + public static class Builder { + @NonNull private SecurityRequirements requirements = new SecurityRequirements(); + + @NonNull + public Builder setAuditLogging(int auditLogging) { + this.requirements.auditLogging = auditLogging; + return this; + } + + @NonNull + public SecurityRequirements build() { + return requirements; + } + } + + public int getAuditLogging() { + return auditLogging; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java similarity index 98% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index c9c7e076b..56f3591a7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java similarity index 97% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java index 725ae2361..b3d06200e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/CustomX509ExtendedTrustManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedTrustManager; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java similarity index 81% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index 9fa814782..4d56b3cd7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/keystores/TLSPreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -1,7 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; import javax.net.ssl.*; import java.io.IOException; @@ -19,7 +16,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TLSPreConfiguration { +public class PreConfiguration { //private static final Logger LOG = LoggerFactory.getLogger(TLSPreConfiguration.class); public static TrustManager[] getX509ExtTrustManager( @@ -41,23 +38,20 @@ public static TrustManager[] getX509ExtTrustManager( new CertPathTrustManagerParameters(filterTrustAnchors(trustStore)); trustManagerFactory.init(trustParams);*/ trustManagerFactory.init(trustStore); - myTrustManager = trustManagerFactory.getTrustManagers(); - /* set up TrustManager config */ //allow only X509 Authentication if (myTrustManager.length == 1 && myTrustManager[0] instanceof X509ExtendedTrustManager) { //toDo algorithm constraints - //toDO hostname verification is currently done by using https identification protocol + //toDo hostname verification is currently done by using https identification protocol return myTrustManager; } else { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(myTrustManager)); } } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException e) { - e.printStackTrace(); + throw new RuntimeException(e); } - return null; } public static KeyManager[] getX509ExtKeyManager( @@ -92,9 +86,33 @@ public static KeyManager[] getX509ExtKeyManager( } catch (IOException | KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e) { - e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public static Key getKey( + String keyStorePath, + String keyStorePassword, + String keyAlias + ) { + try ( + InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)); + ) { + /* create KeyManager for remote authentication */ + KeyStore keystore = KeyStore.getInstance("JKS"); + + //load keystore + keystore.load(jksKeyStoreIn, keyStorePassword.toCharArray()); + + // get private key + return keystore.getKey(keyAlias, + keyStorePassword.toCharArray() + ); + + } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException + | UnrecoverableKeyException e) { + throw new RuntimeException(e); } - return null; //some exception was raised } private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 3e957daec..1daed0d9f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores.TLSPreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; @@ -13,10 +13,8 @@ import javax.net.ssl.*; import java.io.DataOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; -import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.concurrent.CountDownLatch; @@ -67,14 +65,14 @@ public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables * hostVerification and algorithm constraints */ - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + TrustManager[] myTrustManager = PreConfiguration.getX509ExtTrustManager( clientSettings.getTrustStorePath(), clientSettings.getTrustStorePassword() ); /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables * connection specific key selection via key alias*/ - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( clientSettings.getKeyStorePath(), clientSettings.getKeyStorePassword(), clientSettings.getCertAlias(), diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index bad618463..5b0cebd24 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.keystores.TLSPreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; @@ -12,7 +12,6 @@ import javax.net.ssl.*; import java.io.IOException; import java.net.ServerSocket; -import java.net.SocketException; import java.net.SocketTimeoutException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -53,7 +52,7 @@ public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables * hostVerification and algorithm constraints */ LOG.debug("Create trust manager for tls server"); - TrustManager[] myTrustManager = TLSPreConfiguration.getX509ExtTrustManager( + TrustManager[] myTrustManager = PreConfiguration.getX509ExtTrustManager( serverSettings.getTrustStorePath(), serverSettings.getTrustStorePassword() ); @@ -61,7 +60,7 @@ public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables * connection specific key selection via key alias*/ LOG.debug("Create key manager for tls server"); - KeyManager[] myKeyManager = TLSPreConfiguration.getX509ExtKeyManager( + KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( serverSettings.getKeyStorePath(), serverSettings.getKeyStorePassword(), serverSettings.getCertAlias(), diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index 5314c1a35..e6188f504 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -7,5 +7,5 @@ */ public interface DapsDriver { byte[] getToken(); - int verifyToken(byte[] dat); + int verifyToken(byte[] dat, Object securityRequirements); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index a01e931b9..f81f1f70b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -99,7 +99,7 @@ public StateWaitForDatAndRat(FSM fsm, //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); int datValidityPeriod; - if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat))){ + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 035987fc2..0ceb07a01 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -69,7 +69,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); int datValidityPeriod; - if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat))){ + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index ddb7ea88c..52b2ebbb8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -97,7 +97,7 @@ public StateWaitForHello(FSM fsm, byte[] dat; int datValidityPeriod; if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver - .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray()))){ + .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java new file mode 100644 index 000000000..3360e7bd3 --- /dev/null +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -0,0 +1,7 @@ +public class DapsDriverTest { + + public static void main(String[] args) { + System.out.println("test"); + } + +} diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index cda0fa9e5..1b8b0e466 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -1,5 +1,6 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; @@ -19,7 +20,18 @@ public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings settings){ SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); - DapsDriver dapsDriver = new DefaultDapsDriver(); + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(settings.getKeyStorePath()) + .setTrustStorePath(settings.getTrustStorePath()) + .setKeyStorePassword(settings.getKeyStorePassword()) + .setTrustStorePassword(settings.getTrustStorePassword()) + .setKeyAlias(settings.getCertAlias()) + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index e81a21e1e..ce4295f2c 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,5 +1,6 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; @@ -21,7 +22,18 @@ public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); - DapsDriver dapsDriver = new DefaultDapsDriver(); + + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(serverSettings.getKeyStorePath()) + .setTrustStorePath(serverSettings.getTrustStorePath()) + .setKeyStorePassword(serverSettings.getKeyStorePassword()) + .setTrustStorePassword(serverSettings.getTrustStorePassword()) + .setKeyAlias(serverSettings.getCertAlias()) + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + DapsDriver dapsDriver = new DefaultDapsDriver(config); RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); From b5f21b00d65d05c94233e1e8133482cc3eaf73fc Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Wed, 25 Mar 2020 11:18:28 +0100 Subject: [PATCH 053/237] DapsDriver: Update return value to long, return validity time, add some junit tests, add Builder Pattern to settings --- .../daps/DefaultDapsDriver.java | 14 +- .../keystores/PreConfiguration.java | 9 +- .../client/InputListenerThread.java | 3 +- .../idscp2/drivers/interfaces/DapsDriver.java | 2 +- .../configuration/IDSCPv2Settings.java | 94 +++++--- .../StateWaitForDatAndRat.java | 2 +- .../StateWaitForDatAndRatVerifier.java | 2 +- .../StateWaitForHello.java | 2 +- .../finite_state_machine/Timer.java | 4 +- .../finite_state_machine/TimerThread.java | 4 +- idscp2/src/test/java/DapsDriverTest.java | 213 +++++++++++++++++- idscp2/src/test/java/RunTLSClient.java | 11 +- idscp2/src/test/java/RunTLSServer.java | 11 +- 13 files changed, 315 insertions(+), 56 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index c41ef33e7..d708ffc6f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -26,6 +26,8 @@ import org.jose4j.jwk.HttpsJwks; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jwt.JwtClaims; +import org.jose4j.jwt.MalformedClaimException; +import org.jose4j.jwt.NumericDate; import org.jose4j.jwt.consumer.InvalidJwtException; import org.jose4j.jwt.consumer.JwtConsumer; import org.jose4j.jwt.consumer.JwtConsumerBuilder; @@ -165,7 +167,7 @@ public byte[] getToken() { } @Override - public int verifyToken(byte[] dat, Object securityRequirements) { + public long verifyToken(byte[] dat, Object securityRequirements) { LOG.info("Verify dynamic attribute token ..."); @@ -198,15 +200,21 @@ public int verifyToken(byte[] dat, Object securityRequirements) { //verify dat JwtClaims claims; + NumericDate expTime; LOG.debug("Request JWKS from DAPS for validating DAT"); try { claims = jwtConsumer.processToClaims(new String(dat)); + expTime = claims.getExpirationTime(); } catch (InvalidJwtException e) { LOG.error("DAPS response is not a valid DAT format", e); return -1; + } catch (MalformedClaimException e) { + LOG.error("DAT does not contain expiration time", e); + return -1; } + long validityTime = expTime.getValue() - NumericDate.now().getValue(); //check security requirements if (securityRequirements != null) { @@ -225,7 +233,7 @@ public int verifyToken(byte[] dat, Object securityRequirements) { if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) { LOG.info("DAT is valid and secure"); - return 20; + return validityTime; } else { LOG.warn("DAT does not fulfill the security requirements"); return -1; @@ -237,7 +245,7 @@ public int verifyToken(byte[] dat, Object securityRequirements) { } } else { LOG.info("DAT is valid"); - return 20; + return validityTime; } } //returns number of seconds dat is valid diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index 4d56b3cd7..cc8b465a1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -105,9 +105,12 @@ public static Key getKey( keystore.load(jksKeyStoreIn, keyStorePassword.toCharArray()); // get private key - return keystore.getKey(keyAlias, - keyStorePassword.toCharArray() - ); + Key key = keystore.getKey(keyAlias, keyStorePassword.toCharArray()); + if (key == null) { + throw new RuntimeException("No key was found in keystore for given alias"); + } else { + return key; + } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 15c605e8b..8d49dc954 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -36,17 +36,16 @@ public void run(){ byte[] buf; while (running){ try { - int len = in.readInt(); buf = new byte[len]; in.readFully(buf, 0, len); this.listener.onMessage(buf); - } catch (SocketTimeoutException e) { //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye //alternative: close socket / InputStream and catch exception //continue; //toDo offset when timeout while reading ??? + } catch (EOFException e){ listener.onClose(); running = false; //terminate diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index e6188f504..4ae55525d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -7,5 +7,5 @@ */ public interface DapsDriver { byte[] getToken(); - int verifyToken(byte[] dat, Object securityRequirements); + long verifyToken(byte[] dat, Object securityRequirements); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index c77d56a9b..467b97fe9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -1,5 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.units.qual.A; /** @@ -21,6 +22,71 @@ public class IDSCPv2Settings { private AttestationConfig supportedAttestation = new AttestationConfig(); private AttestationConfig expectedAttestation = new AttestationConfig(); + public static class Builder { + @NonNull + private IDSCPv2Settings settings = new IDSCPv2Settings(); + + @NonNull + public Builder setHost(String host) { + this.settings.host = host; + return this; + } + + @NonNull + public Builder setTrustStore(String path) { + this.settings.trustStorePath = path; + return this; + } + + @NonNull + public Builder setKeyStore(String path) { + this.settings.keyStorePath = path; + return this; + } + + @NonNull + public Builder setTrustStorePwd(String pwd) { + this.settings.trustStorePassword = pwd; + return this; + } + + @NonNull + public Builder setKeyStorePwd(String pwd) { + this.settings.keyStorePassword = pwd; + return this; + } + + @NonNull + public Builder setCertificateAlias(String alias) { + this.settings.certAlias = alias; + return this; + } + + @NonNull + public Builder setKeyStoreKeyType(String keyType) { + this.settings.keyStoreKeyType = keyType; + return this; + } + + @NonNull + public Builder setSupportedAttestationSuite(AttestationConfig suite) { + this.settings.supportedAttestation = suite; + return this; + } + + @NonNull + public Builder setExpectedAttestationSuite(AttestationConfig suite) { + this.settings.expectedAttestation = suite; + return this; + } + + @NonNull + public IDSCPv2Settings build() { + return this.settings; + } + + } + public AttestationConfig getExpectedAttestation() { return expectedAttestation; } @@ -57,35 +123,7 @@ public String getCertAlias() { return certAlias; } - public void setKeyStorePath(String keyStorePath) { - this.keyStorePath = keyStorePath; - } - - public void setTrustStorePath(String trustStorePath) { - this.trustStorePath = trustStorePath; - } - - public void setCertAlias(String certAlias) { - this.certAlias = certAlias; - } - - public void setKeyStoreKeyType(String keyStoreKeyType) { - this.keyStoreKeyType = keyStoreKeyType; - } - - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } - - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - public String getHost() { return host; } - - public void setHost(String host) { - this.host = host; - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index f81f1f70b..e0336ed01 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -98,7 +98,7 @@ public StateWaitForDatAndRat(FSM fsm, LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - int datValidityPeriod; + long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 0ceb07a01..1118112c8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -68,7 +68,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); - int datValidityPeriod; + long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index 52b2ebbb8..323155f3e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -95,7 +95,7 @@ public StateWaitForHello(FSM fsm, LOG.debug("Verify received DAT"); //check if Dat is available and verify dat byte[] dat; - int datValidityPeriod; + long datValidityPeriod; if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index 9eb2e25b5..0496fa7a1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -16,12 +16,12 @@ public class Timer { this.timeoutHandler = timeoutHandler; } - void resetTimeout(int delay){ + void resetTimeout(long delay){ cancelTimeout(); start(delay); } - public void start(int delay){ + public void start(long delay){ mutex.lock(); thread = new TimerThread(delay, timeoutHandler, fsmIsBusy); thread.start(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index 2efc7109c..1f6041336 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -5,11 +5,11 @@ public class TimerThread extends Thread{ private volatile boolean canceled = false; - private int delay; + private long delay; private final Runnable timeoutHandler; private final ReentrantLock fsmIsBusy; - TimerThread(int delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy){ + TimerThread(long delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy){ this.delay = delay; this.timeoutHandler = timeoutHandler; this.fsmIsBusy = fsmIsBusy; diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 3360e7bd3..1e8d17762 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -1,7 +1,216 @@ +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.SecurityRequirements; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import org.junit.Test; +import static org.junit.Assert.*; + public class DapsDriverTest { + //toDo add further junit tests - public static void main(String[] args) { - System.out.println("test"); + private String getExpiredToken() { + return ""; + } + + @Test + public void testValidToken() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + assertNotEquals(token, "INVALID_TOKEN"); + + SecurityRequirements requirements = new SecurityRequirements.Builder() + .setAuditLogging(2) + .build(); + + SecurityRequirements requirements2 = new SecurityRequirements.Builder() + .setAuditLogging(1) + .build(); + + assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) >= 0); + assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements2) >= 0); + } + + @Test + public void testInvalidClient() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("INVALID_CLIENT") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + assertEquals(token, "INVALID_TOKEN"); + } + + @Test + public void testInvalidUrlNonSecure() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("http://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + assertEquals(token, "INVALID_TOKEN"); + } + + @Test + public void testInvalidUrl404() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de/token") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + assertEquals(token, "INVALID_TOKEN"); + } + + @Test (expected = RuntimeException.class) + public void testInvalidPassword1() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("INVALID_PASSWORD") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + } + + @Test (expected = RuntimeException.class) + public void testInvalidPassword2() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("INVALID_PASSWORD") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + } + + @Test (expected = RuntimeException.class) + public void testInvalidKeyAlias() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("INVALID_ALIAS") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + } + + @Test + public void testInvalidAuditLogging() { + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + assertNotEquals(token, "INVALID_TOKEN"); + + SecurityRequirements requirements = new SecurityRequirements.Builder() + .setAuditLogging(3) //token has supports only audit_logging 2 + .build(); + + assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); } + public static void main(String[] args) { + //get token + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(DapsDriverTest.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePassword("password") + .setTrustStorePassword("password") + .setKeyAlias("1") + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + + DapsDriver dapsDriver = new DefaultDapsDriver(config); + String token = new String(dapsDriver.getToken()); + System.out.println(token); + + SecurityRequirements requirements = new SecurityRequirements.Builder() + .setAuditLogging(2) + .build(); + + long ret; + if (0 > (ret = dapsDriver.verifyToken(token.getBytes(), requirements))) { + System.out.println("failed"); + } else { + System.out.println("success: " + ret); + } + } } diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java index 2381d1071..5ae1fc94d 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/test/java/RunTLSClient.java @@ -5,11 +5,12 @@ public class RunTLSClient { public static void main(String[] args){ //start client - IDSCPv2Settings settings = new IDSCPv2Settings(); - settings.setKeyStorePath(RunTLSClient.class.getClassLoader(). - getResource("ssl/aisecconnector1-keystore.jks").getPath()); - settings.setTrustStorePath(RunTLSClient.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()); + IDSCPv2Settings settings = new IDSCPv2Settings.Builder() + .setKeyStore(RunTLSClient.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStore(RunTLSClient.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .build(); IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); initiator.init(settings); diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/test/java/RunTLSServer.java index 8265950ff..f227998f2 100644 --- a/idscp2/src/test/java/RunTLSServer.java +++ b/idscp2/src/test/java/RunTLSServer.java @@ -4,11 +4,12 @@ public class RunTLSServer{ public static void main(String[] argv){ - IDSCPv2Settings settings = new IDSCPv2Settings(); - settings.setKeyStorePath(RunTLSServer.class.getClassLoader(). - getResource("ssl/aisecconnector2-keystore.jks").getPath()); - settings.setTrustStorePath(RunTLSServer.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()); + IDSCPv2Settings settings = new IDSCPv2Settings.Builder() + .setKeyStore(RunTLSClient.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setTrustStore(RunTLSServer.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .build(); IDSCPv2ServerInitiator initiator = new IDSCPv2ServerInitiator(); initiator.init(settings); From 513e314f45efb727a42fb1882d5dd7fe65de6964 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Wed, 25 Mar 2020 13:42:01 +0100 Subject: [PATCH 054/237] FIX problems: add special daps key alias in settings, catch SSLHandshakeException in TLSServerThread --- .../secure_channel/server/TLSServerThread.java | 6 +++++- .../idscp_core/configuration/IDSCPv2Settings.java | 11 +++++++++++ .../idscp2/idscp_core/finite_state_machine/FSM.java | 2 +- idscp2/src/test/java/IDSCPv2ClientInitiator.java | 2 +- idscp2/src/test/java/IDSCPv2ServerInitiator.java | 2 +- idscp2/src/test/java/RunTLSClient.java | 2 ++ idscp2/src/test/java/RunTLSServer.java | 4 +++- 7 files changed, 24 insertions(+), 5 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index bd1bad248..0aa00b7f8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -5,6 +5,7 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; +import javax.net.ssl.SSLHandshakeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -86,8 +87,11 @@ public void run(){ } catch (EOFException e){ onClose(); running = false; + } catch (SSLHandshakeException e) { + LOG.warn("SSLHandshakeException occurred. Quit server session"); + running = false; } catch (IOException e){ - onError(); + onError(); //FIXME ??? is there any other exception that could occur before fsm was created ??, if so -> Thread will run forever running = false; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index 467b97fe9..d427fc296 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -18,6 +18,7 @@ public class IDSCPv2Settings { private String keyStorePath = null; private String keyStorePassword = "password"; private String certAlias = "1.0.1"; + private String dapsKeyAlias = "1"; private String keyStoreKeyType = "RSA"; private AttestationConfig supportedAttestation = new AttestationConfig(); private AttestationConfig expectedAttestation = new AttestationConfig(); @@ -62,6 +63,12 @@ public Builder setCertificateAlias(String alias) { return this; } + @NonNull + public Builder setDapsKeyAlias(String alias) { + this.settings.dapsKeyAlias = alias; + return this; + } + @NonNull public Builder setKeyStoreKeyType(String keyType) { this.settings.keyStoreKeyType = keyType; @@ -123,6 +130,10 @@ public String getCertAlias() { return certAlias; } + public String getDapsKeyAlias() { + return dapsKeyAlias; + } + public String getHost() { return host; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index f0f988e60..daa915228 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -58,7 +58,7 @@ enum FSM_STATE { private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private final int ratTimeoutDelay = 120; + private final int ratTimeoutDelay = 20; public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, String[] localSupportedRatSuite, String[] localExpectedRatSuite){ diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 1b8b0e466..62f96526d 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -27,7 +27,7 @@ public void init(IDSCPv2Settings settings){ .setTrustStorePath(settings.getTrustStorePath()) .setKeyStorePassword(settings.getKeyStorePassword()) .setTrustStorePassword(settings.getTrustStorePassword()) - .setKeyAlias(settings.getCertAlias()) + .setKeyAlias(settings.getDapsKeyAlias()) .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index ce4295f2c..03fc7f1b6 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -30,7 +30,7 @@ public void init(IDSCPv2Settings serverSettings) { .setTrustStorePath(serverSettings.getTrustStorePath()) .setKeyStorePassword(serverSettings.getKeyStorePassword()) .setTrustStorePassword(serverSettings.getTrustStorePassword()) - .setKeyAlias(serverSettings.getCertAlias()) + .setKeyAlias(serverSettings.getDapsKeyAlias()) .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java index 5ae1fc94d..87500b62c 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/test/java/RunTLSClient.java @@ -10,6 +10,8 @@ public static void main(String[] args){ getResource("ssl/aisecconnector1-keystore.jks").getPath()) .setTrustStore(RunTLSClient.class.getClassLoader(). getResource("ssl/client-truststore_new.jks").getPath()) + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") .build(); IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/test/java/RunTLSServer.java index f227998f2..e2f9e4f91 100644 --- a/idscp2/src/test/java/RunTLSServer.java +++ b/idscp2/src/test/java/RunTLSServer.java @@ -6,9 +6,11 @@ public static void main(String[] argv){ IDSCPv2Settings settings = new IDSCPv2Settings.Builder() .setKeyStore(RunTLSClient.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()) + getResource("ssl/aisecconnector1-keystore.jks").getPath()) .setTrustStore(RunTLSServer.class.getClassLoader(). getResource("ssl/client-truststore_new.jks").getPath()) + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") .build(); IDSCPv2ServerInitiator initiator = new IDSCPv2ServerInitiator(); From bdcfee6c64e5122cc03f78da147eb11ae9b5fd18 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Thu, 26 Mar 2020 23:51:53 +0100 Subject: [PATCH 055/237] WIP Implement TPM2d RAT Drivers, move idscpv2 + tpm2dattestation protobufs into idscpv2 protocol --- ids-api/src/main/proto/idscpv2.proto | 67 ---- idscp2/build.gradle | 22 ++ .../rat/TPM2d/TPM2dHelper.java | 80 +++++ .../rat/TPM2d/TPM2dProver.java | 157 ++++++++++ .../rat/TPM2d/TPM2dSocket.java | 31 ++ .../rat/TPM2d/TPM2dVerifier.java | 285 ++++++++++++++++++ .../rat/TPM2d/Tpm2dConfig.java | 51 ++++ .../rat/TPM2d/TpmMessageFactory.java | 104 +++++++ .../RatProverDummy.java} | 16 +- .../RatVerifierDummy.java} | 10 +- .../idscp_core/IdscpMessageFactory.java | 12 +- .../idscp_core/finite_state_machine/FSM.java | 4 +- .../finite_state_machine/Timer.java | 2 - idscp2/src/main/proto/idscpv2.proto | 66 ++++ idscp2/src/main/proto/tpm2dAttestation.proto | 147 +++++++++ .../src/test/java/IDSCPv2ClientInitiator.java | 8 +- .../src/test/java/IDSCPv2ServerInitiator.java | 9 +- idscp2/src/test/java/RatDriverTest.java | 11 + 18 files changed, 982 insertions(+), 100 deletions(-) delete mode 100644 ids-api/src/main/proto/idscpv2.proto create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2Prover.java => dummy/RatProverDummy.java} (76%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2Verifier.java => dummy/RatVerifierDummy.java} (84%) create mode 100644 idscp2/src/main/proto/idscpv2.proto create mode 100644 idscp2/src/main/proto/tpm2dAttestation.proto create mode 100644 idscp2/src/test/java/RatDriverTest.java diff --git a/ids-api/src/main/proto/idscpv2.proto b/ids-api/src/main/proto/idscpv2.proto deleted file mode 100644 index 88fab12cf..000000000 --- a/ids-api/src/main/proto/idscpv2.proto +++ /dev/null @@ -1,67 +0,0 @@ -syntax = "proto3"; -option java_package = "de.fhg.aisec.ids.messages"; -option java_outer_classname = "IDSCPv2"; - -//IDSCP message frame -message IdscpMessage { - // One of the following will be filled in. - oneof message { - IdscpHello idscpHello = 1; - IdscpClose idscpClose = 2; - IdscpDatExpired idscpDatExpired = 3; - IdscpDat idscpDat = 4; - IdscpReRat idscpReRat = 5; - IdscpRatProver idscpRatProver = 6; - IdscpRatVerifier idscpRatVerifier = 7; - IdscpData idscpData = 8; - } -} - - -//IDSCP messages -message IdscpHello { - int32 version = 1; //IDSCP protocol version - IdscpDat dynamicAttributeToken = 2; //initial dynamicAttributeToken - repeated string supportedRatSuite = 3; //RemoteAttestationCipher prover - repeated string expectedRatSuite = 4; //RemoteAttestationCipher verifier -} - -message IdscpClose { - - enum CloseCause { - USER_SHUTDOWN = 0; - TIMEOUT = 1; - ERROR = 2; - NO_VALID_DAT = 3; - NO_RAT_MECHANISM_MATCH_PROVER = 4; - NO_RAT_MECHANISM_MATCH_VERIFIER = 5; - RAT_PROVER_FAILED = 6; - RAT_VERIFIER_FAILED = 7; - } - - CloseCause cause_code = 1; - string cause_msg = 2; -} - -message IdscpDatExpired { //request new dynamicAttributeToken -} - -message IdscpDat { - bytes token = 1; -} - -message IdscpReRat { //request new remoteAttestation - string cause = 1; //optional -} - -message IdscpRatProver { - bytes data = 1; -} - -message IdscpRatVerifier { - bytes data = 1; -} - -message IdscpData { - bytes data = 1 ; -} diff --git a/idscp2/build.gradle b/idscp2/build.gradle index e48f54184..ae7629c0f 100644 --- a/idscp2/build.gradle +++ b/idscp2/build.gradle @@ -1,5 +1,27 @@ version = libraryVersions.idscp +apply plugin: 'com.google.protobuf' +apply plugin: 'idea' + +protobuf { + generatedFilesBaseDir = "$projectDir/generated" + + protoc { + artifact = "com.google.protobuf:protoc:${libraryVersions.protobuf}" + } +} + +clean { + delete protobuf.generatedFilesBaseDir +} + +idea { + module { + // mark as generated sources for IDEA + generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") + } +} + dependencies { providedByBundle(project(':ids-api')) { transitive = false } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java new file mode 100644 index 000000000..7c10ad4d9 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java @@ -0,0 +1,80 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TPM2dHelper { + private static final Logger LOG = LoggerFactory.getLogger(TPM2dHelper.class); + private static final SecureRandom sr = new SecureRandom(); + + private TPM2dHelper() {} + + /** + * Generate a crypto-secure random hex String of length numChars + * + * @param numBytes Desired String length + * @return The generated crypto-secure random hex String + */ + static byte[] generateNonce(int numBytes) { + byte[] randBytes = new byte[numBytes]; + sr.nextBytes(randBytes); + return randBytes; + } + + /** + * Calculate SHA-1 hash of (nonce|certificate). + * + * @param nonce The plain, initial nonce + * @param certificate The certificate to hash-combine with the nonce + * @return The new nonce, updated with the given certificate using SHA-1 + */ + static byte[] calculateHash(byte[] nonce, @Nullable Certificate certificate) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(nonce); + if (certificate != null) { + digest.update(certificate.getEncoded()); + } else { + LOG.warn( + "No client certificate available. Cannot bind nonce to public key to prevent masquerading attack. TLS misconfiguration!"); + } + return digest.digest(); + } catch (Exception e1) { + LOG.error("Could not create hash of own nonce and local certificate", e1); + return nonce; + } + } + + static class ByteArrayUtil { + + private static final String[] lookup = new String[256]; + + static { + for (int i = 0; i < lookup.length; ++i) { + if (i < 16) { + lookup[i] = "0" + Integer.toHexString(i); + } else { + lookup[i] = Integer.toHexString(i); + } + } + } + + static String toPrintableHexString(byte[] bytes) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < bytes.length; ++i) { + if (i > 0 && i % 16 == 0) { + s.append('\n'); + } else { + s.append(' '); + } + s.append(lookup[bytes[i] & 0xff]); + } + return s.toString(); + } + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java new file mode 100644 index 000000000..4be3d812b --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java @@ -0,0 +1,157 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import com.google.protobuf.InvalidProtocolBufferException; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; + +import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatChallenge; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResult; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dToRemote; +import java.io.IOException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class TPM2dProver extends RatProverDriver { + private static final Logger LOG = LoggerFactory.getLogger(TPM2dProver.class); + + private BlockingQueue queue = new LinkedBlockingQueue<>(); + + public TPM2dProver(){ + super(); + } + + @Override + public void delegate(IdscpMessage message) { + queue.add(message); + LOG.debug("Delegated to prover"); + } + + @Override + public void run() { + //TPM2d Challenge-Response Protocol + + // wait for RatChallenge from Verifier + IdscpMessage msg; + try { + msg = queue.take(); + LOG.debug("Prover receives new message"); + } catch (InterruptedException e) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if message is from rat verifier + if (!msg.hasIdscpRatVerifier()) { + //unexpected message + LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // parse body to expected tpm2d message wrapper + Tpm2dMessageWrapper tpm2dMessageWrapper; + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatVerifier().getData()); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatVerifier body", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if wrapper contains expected rat challenge + if (!tpm2dMessageWrapper.hasRatChallenge()) { + //unexpected message + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatChallenge"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + LOG.debug("Get rat challenge from rat verifier"); + Tpm2dRatChallenge challenge = tpm2dMessageWrapper.getRatChallenge(); + + LOG.debug("Requesting attestation from TPM ..."); + // hash //toDo add remote certificate + byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), null); + + // generate RemoteToTPM2dRequest + RemoteToTpm2d tpmRequest = TpmMessageFactory.getRemoteToTPM2dMessage( + challenge.getAtype(), + hash, + challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 //toDo 0 okay? + ); + + // get TPM response + Tpm2dToRemote tpmResponse; + try { + TPM2dSocket tpmSocket = new TPM2dSocket(""); //toDo add host + tpmResponse = tpmSocket.requestAttestation(tpmRequest); + } catch (IOException e) { + LOG.error("Cannot access TPM", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // create Tpm2dResponse + byte[] response = TpmMessageFactory.getAttestationResponseMessage(tpmResponse) + .toByteArray(); + + LOG.debug("Send rat response to verifier"); + fsmListener.onRatProverMessage( + InternalControlMessage.RAT_PROVER_MSG, + IdscpMessageFactory.getIdscpRatProverMessage(response) + ); + + // wait for result + try { + msg = queue.take(); + LOG.debug("Prover receives new message"); + } catch (InterruptedException e) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if message is from rat verifier + if (!msg.hasIdscpRatVerifier()) { + //unexpected message + LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // parse body to expected tpm2d message wrapper + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatVerifier().getData()); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatVerifier body", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if wrapper contains expected rat result + if (!tpm2dMessageWrapper.hasRatResult()) { + //unexpected message + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResult"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + LOG.debug("Get rat challenge from rat verifier"); + Tpm2dRatResult result = tpm2dMessageWrapper.getRatResult(); + + // notify fsm + if (result.getResult()) { + LOG.debug("Attestation succeed"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); + } else { + LOG.warn("Attestation failed"); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + } + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java new file mode 100644 index 000000000..6f3bd3ce9 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java @@ -0,0 +1,31 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dToRemote; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; + +public class TPM2dSocket extends Socket { + + private final DataInputStream is; + private final DataOutputStream os; + + public TPM2dSocket(String host) throws IOException { + super(host, 9505); + is = new DataInputStream(this.getInputStream()); + os = new DataOutputStream(this.getOutputStream()); + } + + public Tpm2dToRemote requestAttestation(RemoteToTpm2d request) throws IOException { + // Write attestation request message + byte[] requestBytes = request.toByteArray(); + os.writeInt(requestBytes.length); + os.write(requestBytes); + // Read attestation result message + byte[] resultBytes = new byte[is.readInt()]; + is.readFully(resultBytes); + return Tpm2dToRemote.parseFrom(resultBytes); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java new file mode 100644 index 000000000..e10fcf5b6 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java @@ -0,0 +1,285 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import com.google.protobuf.InvalidProtocolBufferException; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; +import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResponse; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.Signature; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Base64; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import tss.tpm.TPMS_ATTEST; +import tss.tpm.TPMS_SIGNATURE_RSAPSS; +import tss.tpm.TPMS_SIGNATURE_RSASSA; +import tss.tpm.TPMT_SIGNATURE; +import tss.tpm.TPM_ALG_ID; + +public class TPM2dVerifier extends RatVerifierDriver { + private static final Logger LOG = LoggerFactory.getLogger(TPM2dVerifier.class); + + private BlockingQueue queue = new LinkedBlockingQueue<>(); + private Tpm2dConfig config = new Tpm2dConfig.Builder().build(); + + public TPM2dVerifier(){ + super(); + } + + @Override + public void delegate(IDSCPv2.IdscpMessage message) { + queue.add(message); + LOG.debug("Delegated to Verifier"); + } + + @Override + public void run(){ + //TPM2d Challenge-Response Protocol + + // create rat challenge with fresh nonce + LOG.debug("Generate and send rat challenge for rat prover"); + byte[] nonce = TPM2dHelper.generateNonce(20); + + // send challenge as RAT Verifier Message + byte[] ratChallenge = TpmMessageFactory.getAttestationChallengeMessage( + nonce, config.getExpectedAType(), config.getAttestationMask()).toByteArray(); + + fsmListener.onRatVerifierMessage( + InternalControlMessage.RAT_VERIFIER_MSG, + IdscpMessageFactory.getIdscpRatVerifierMessage(ratChallenge) + ); + + // wait for attestation response + IdscpMessage msg; + try { + msg = queue.take(); + LOG.debug("Verifier receives new message"); + } catch (InterruptedException e) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } + + // check if response is from rat prover + if (!msg.hasIdscpRatProver()) { + //unexpected message + LOG.warn("Unexpected message from FSM: Expected IdscpRatVerifier"); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } + + // parse body to expected tpm2d message wrapper + Tpm2dMessageWrapper tpm2dMessageWrapper; + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatProver().getData()); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatProver body", e); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } + + // check if wrapper contains expected rat response + if (!tpm2dMessageWrapper.hasRatResponse()) { + //unexpected message + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResponse"); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } + + LOG.debug("Get rat response from remote prover"); + //validate rat response + Tpm2dRatResponse resp = tpm2dMessageWrapper.getRatResponse(); + + LOG.debug("Validate rat response: signature and rat repository checks"); + // validate signature //toDo add local certificate + boolean result = true; + byte[] hash = TPM2dHelper.calculateHash(nonce, null); + + if (!checkSignature(resp, hash)) { + result = false; + LOG.warn("Invalid rat signature"); + } + + // toDo check rat repo!!!!!!!!! --> Problems with current Rat Repo Protobuf format + + // create and send rat result + LOG.debug("Send rat result to remote prover"); + byte[] ratResult = TpmMessageFactory.getAttestationResultMessage(result).toByteArray(); + fsmListener.onRatVerifierMessage( + InternalControlMessage.RAT_VERIFIER_MSG, + IdscpMessageFactory.getIdscpRatVerifierMessage(ratResult) + ); + + // notify fsm about result + if (result) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); + } else { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + } + } + + private boolean checkSignature(@NonNull Tpm2dRatResponse response, byte[] hash) { + byte[] byteSignature = response.getSignature().toByteArray(); + byte[] byteCert = response.getCertificate().toByteArray(); + byte[] byteQuoted = response.getQuoted().toByteArray(); + + if (LOG.isDebugEnabled()) { + LOG.debug("signature: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature)); + LOG.debug("cert: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteCert)); + LOG.debug("quoted: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted)); + } + + if (byteSignature.length == 0 || byteCert.length == 0 || byteQuoted.length == 0) { + LOG.warn("Some required part (signature, cert or quoted) is empty!"); + return false; + } + + try { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + + // Load trust anchor certificate + final X509Certificate rootCertificate; + Path rootCertPath = FileSystems.getDefault().getPath("etc", "rootca-cert.pem"); + try (BufferedReader reader = + Files.newBufferedReader(rootCertPath, StandardCharsets.US_ASCII)) { + StringBuilder builder = new StringBuilder(); + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (!line.startsWith("-")) { + builder.append(line.trim()); + } + } + byte[] rootCertBytes = Base64.getDecoder().decode(builder.toString()); + rootCertificate = + (X509Certificate) + certFactory.generateCertificate(new ByteArrayInputStream(rootCertBytes)); + } catch (Exception e) { + LOG.error("Error parsing root certificate", e); + return false; + } + + // Create X509Certificate instance from certBytes + final X509Certificate certificate = + (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(byteCert)); + // Verify the TPM certificate + try { + certificate.verify(rootCertificate.getPublicKey()); + } catch (Exception e) { + LOG.error("TPM certificate is invalid", e); + return false; + } + + // Construct a new TPMT_SIGNATURE instance from byteSignature bytes + final TPMT_SIGNATURE tpmtSignature; + try { + tpmtSignature = TPMT_SIGNATURE.fromTpm(byteSignature); + } catch (Exception ex) { + LOG.warn( + "Could not create a TPMT_SIGNATURE from bytes:\n" + + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature), + ex); + return false; + } + + // Construct a new TPMS_ATTEST instance from byteQuoted bytes + final TPMS_ATTEST tpmsAttest; + try { + tpmsAttest = TPMS_ATTEST.fromTpm(byteQuoted); + } catch (Exception ex) { + LOG.warn( + "Could not create a TPMS_ATTEST from bytes:\n" + + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted), + ex); + return false; + } + + // check hash value (extra data) against expected hash + byte[] extraBytes = tpmsAttest.extraData; + if (!Arrays.equals(extraBytes, hash)) { + if (LOG.isWarnEnabled()) { + LOG.warn( + "The hash (extra data) in TPMS_ATTEST structure is invalid!" + + "\nextra data: {}\nhash: {}", + TPM2dHelper.ByteArrayUtil.toPrintableHexString(extraBytes), + TPM2dHelper.ByteArrayUtil.toPrintableHexString(hash)); + } + return false; + } + + // Check signature of attestation + final int tpmSigAlg = tpmtSignature.GetUnionSelector_signature(); + final int tpmSigHashAlg; + final byte[] tpmSig; + if (tpmSigAlg == TPM_ALG_ID.RSAPSS.toInt()) { + tpmSigHashAlg = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).hash.toInt(); + tpmSig = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).sig; + } else if (tpmSigAlg == TPM_ALG_ID.RSASSA.toInt()) { + tpmSigHashAlg = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).hash.toInt(); + tpmSig = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).sig; + } else { + throw new Exception( + "Unknown or unimplemented signature scheme: " + tpmtSignature.signature.getClass()); + } + if (tpmSigHashAlg != TPM_ALG_ID.SHA256.toInt()) { + throw new Exception("Only SHA256withRSA TPM signature hash algorithm is allowed!"); + } + Signature sig = Signature.getInstance("SHA256withRSA"); + sig.initVerify(certificate.getPublicKey()); + sig.update(byteQuoted); + boolean result = sig.verify(tpmSig); + if (!result && LOG.isWarnEnabled()) { + LOG.warn("Attestation signature invalid!"); + } + return result; + } catch (Exception ex) { + LOG.warn("Error during attestation validation", ex); + return false; + } + } + + /* + * ******************* New Protocol ******************* + * + * Verifier: (Challenger) + * ------------------------- + * Generate NonceV + * create RatChallenge (NonceV, aType, pcr_mask) + * ------------------------- + * + * Prover: (Responder) + * ------------------------- + * get RatChallenge (NonceV, aType, pcr_mask) + * hash = calculateHash(nonceV, certV) + * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) + * response = TPM2dToRemote = tpmSocket.attestationRequest(req) + * create AttestationResponse from tpm response + * ------------------------- + * + * Verifier: (Responder) + * ------------------------- + * get AttestationResponse + * hash = calculateHash(nonceV, certV) + * check signature(response, hash) + * check repo(aType, response, ttpUri) + * create RatResult + * ------------------------- + * + * Prover: (Requester) + * ------------------------- + * get AttestationResult + * ------------------------- + * + */ +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java new file mode 100644 index 000000000..84a950314 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java @@ -0,0 +1,51 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import de.fhg.aisec.ids.messages.Tpm2dAttestation.IdsAttestationType; +import java.net.URI; +import org.checkerframework.checker.nullness.qual.NonNull; + +public class Tpm2dConfig { + + private int attestationMask = 0; + @NonNull private IdsAttestationType expectedAType = IdsAttestationType.BASIC; + @NonNull private URI ttpUri = URI.create(""); + + public static class Builder { + @NonNull private Tpm2dConfig config = new Tpm2dConfig(); + + @NonNull + public Builder setAttestationMask(int attestationMask) { + config.attestationMask = attestationMask; + return this; + } + + @NonNull + public Builder setIdsAttestationType(IdsAttestationType aType) { + config.expectedAType = aType; + return this; + } + + @NonNull + public Builder setTtpUri(URI ttp) { + config.ttpUri = ttp; + return this; + } + + @NonNull + public Tpm2dConfig build() { + return config; + } + } + + public IdsAttestationType getExpectedAType() { + return expectedAType; + } + + public int getAttestationMask() { + return attestationMask; + } + + public URI getTtpUri() { + return ttpUri; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java new file mode 100644 index 000000000..1379fdbec --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java @@ -0,0 +1,104 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + + +import com.google.protobuf.ByteString; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d.Code; +import java.util.List; + +public class TpmMessageFactory { + + static Tpm2dMessageWrapper getAttestationChallengeMessage( + byte[] nonce, + IdsAttestationType aType, + int pcrIndices + ) { + return Tpm2dMessageWrapper.newBuilder().setRatChallenge( + Tpm2dRatChallenge.newBuilder() + .setAtype(aType) + .setNonce(ByteString.copyFrom(nonce)) + .setPcrIndices(pcrIndices) + .build() + ).build(); + } + + static Tpm2dMessageWrapper getAttestationResponseMessage( + IdsAttestationType aType, + String hash_alg, + ByteString quoted, + ByteString signature, + List pcrValues, + ByteString certificate + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResponse( + Tpm2dRatResponse.newBuilder() + .setAtype(aType) + .setHashAlg(hash_alg) + .setQuoted(quoted) + .setSignature(signature) + .addAllPcrValues(pcrValues) + .setCertificate(certificate) + .build() + ).build(); + } + + static Tpm2dMessageWrapper getAttestationResponseMessage( + Tpm2dToRemote response + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResponse( + Tpm2dRatResponse.newBuilder() + .setAtype(response.getAtype()) + .setHashAlg(response.getHalg().name()) + .setQuoted(response.getQuoted()) + .setSignature(response.getSignature()) + .addAllPcrValues(response.getPcrValuesList()) + .setCertificate(response.getCertificate()) + .build() + ).build(); + } + + static Tpm2dMessageWrapper getAttestationResultMessage( + //IdsAttestationType aType, + boolean result + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResult( + Tpm2dRatResult.newBuilder() + //.setAtype(aType) + .setResult(result) + .build() + ).build(); + } + + static Tpm2dMessageWrapper getAttestationRepositoryRequestMessage( + IdsAttestationType aType, + List pcrValues + ) { + return Tpm2dMessageWrapper.newBuilder().setRepositoryRequest( + Tpm2dRepositoryRequest.newBuilder() + .setAtype(aType) + .addAllPcrValues(pcrValues) + .build() + ).build(); + } + + static Tpm2dMessageWrapper getAttestationRepositoryResponseMessage() { + return Tpm2dMessageWrapper.newBuilder().setRepositoryResponse( + Tpm2dRepositoryResponse.newBuilder() + //toDo add values + .build() + ).build(); + } + + static RemoteToTpm2d getRemoteToTPM2dMessage( + IdsAttestationType aType, + byte[] hash, + int pcrIndices + ) { + return RemoteToTpm2d.newBuilder() + .setAtype(aType) + .setQualifyingData(ByteString.copyFrom(hash)) + .setCode(Code.ATTESTATION_REQ) + .setPcrs(pcrIndices) + .build(); + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java similarity index 76% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 55bbf061b..90a8786a3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Prover.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; @@ -8,24 +8,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.LinkedList; -import java.util.Queue; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; /** * A RatProver dummy, that sends two incoming messages from the remote rat verifier and also sends two messages */ -public class TPM2Prover extends RatProverDriver { - private static final Logger LOG = LoggerFactory.getLogger(TPM2Prover.class); +public class RatProverDummy extends RatProverDriver { + private static final Logger LOG = LoggerFactory.getLogger(RatProverDummy.class); private BlockingQueue queue = new LinkedBlockingQueue<>(); - public TPM2Prover(){ + public RatProverDummy(){ super(); } @@ -42,7 +36,7 @@ public void run() { try { sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, - IdscpMessageFactory.getIdscpRatProverMessage()); + IdscpMessageFactory.getIdscpRatProverMessage("test".getBytes())); LOG.debug("Prover waits"); IDSCPv2.IdscpMessage m = queue.take(); LOG.debug("Prover receives, send something"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java similarity index 84% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index c7d302715..dacda0537 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2Verifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; @@ -10,12 +10,12 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -public class TPM2Verifier extends RatVerifierDriver { - private static final Logger LOG = LoggerFactory.getLogger(TPM2Verifier.class); +public class RatVerifierDummy extends RatVerifierDriver { + private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDummy.class); private BlockingQueue queue = new LinkedBlockingQueue<>(); - public TPM2Verifier(){ + public RatVerifierDummy(){ super(); } @@ -35,7 +35,7 @@ public void run(){ IDSCPv2.IdscpMessage m = queue.take(); LOG.debug("Verifier receives, send something"); fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, - IdscpMessageFactory.getIdscpRatVerifierMessage()); + IdscpMessageFactory.getIdscpRatVerifierMessage("test".getBytes())); if (--countDown == 0) break; } catch (InterruptedException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index 3b917571a..f565a3f7f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -71,16 +71,20 @@ public static IdscpMessage getIdscpDataMessage(byte[] data){ .build(); } - public static IdscpMessage getIdscpRatProverMessage(){ - IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder().build(); + public static IdscpMessage getIdscpRatProverMessage(byte[] body){ + IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder() + .setData(ByteString.copyFrom(body)) + .build(); return IdscpMessage.newBuilder() .setIdscpRatProver(idscpRatProver) .build(); } - public static IdscpMessage getIdscpRatVerifierMessage(){ - IdscpRatVerifier idscpRatVerifier = IdscpRatVerifier.newBuilder().build(); + public static IdscpMessage getIdscpRatVerifierMessage(byte[] body){ + IdscpRatVerifier idscpRatVerifier = IdscpRatVerifier.newBuilder() + .setData(ByteString.copyFrom(body)) + .build(); return IdscpMessage.newBuilder() .setIdscpRatVerifier(idscpRatVerifier) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index daa915228..e510564fa 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -310,7 +310,7 @@ void restartRatVerifierDriver(){ if (ratVerifierDriver == null){ LOG.error("Cannot create instance of RAT_VERIFIER_DRIVER"); currentRatVerifierId = ""; - onControlMessage(InternalControlMessage.ERROR); //toDo geht das? + onControlMessage(InternalControlMessage.ERROR); //toDo geht das? nein } else { currentRatVerifierId = Long.toString(ratVerifierDriver.getId()); } @@ -330,7 +330,7 @@ void restartRatProverDriver(){ if (ratProverDriver == null){ LOG.error("Cannot create instance of RAT_PROVER_DRIVER"); currentRatProverId = ""; - onControlMessage(InternalControlMessage.ERROR); //toDo geht das? + onControlMessage(InternalControlMessage.ERROR); //toDo geht das? nein } else { currentRatProverId = Long.toString(ratProverDriver.getId()); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index 0496fa7a1..7ddfd07c0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -4,8 +4,6 @@ public class Timer { - //toDo real time FIFO synchronization for whole state machine - private TimerThread thread = null; private final ReentrantLock fsmIsBusy; private final ReentrantLock mutex = new ReentrantLock(true); diff --git a/idscp2/src/main/proto/idscpv2.proto b/idscp2/src/main/proto/idscpv2.proto new file mode 100644 index 000000000..658d2e6c8 --- /dev/null +++ b/idscp2/src/main/proto/idscpv2.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +option java_package = "de.fhg.aisec.ids.messages"; +option java_outer_classname = "IDSCPv2"; + +//IDSCP message frame +message IdscpMessage { + // One of the following will be filled in. + oneof message { + IdscpHello idscpHello = 1; + IdscpClose idscpClose = 2; + IdscpDatExpired idscpDatExpired = 3; + IdscpDat idscpDat = 4; + IdscpReRat idscpReRat = 5; + IdscpRatProver idscpRatProver = 6; + IdscpRatVerifier idscpRatVerifier = 7; + IdscpData idscpData = 8; + } +} + +//IDSCP messages +message IdscpHello { + int32 version = 1; //IDSCP protocol version + IdscpDat dynamicAttributeToken = 2; //initial dynamicAttributeToken + repeated string supportedRatSuite = 3; //RemoteAttestationCipher prover + repeated string expectedRatSuite = 4; //RemoteAttestationCipher verifier +} + +message IdscpClose { + + enum CloseCause { + USER_SHUTDOWN = 0; + TIMEOUT = 1; + ERROR = 2; + NO_VALID_DAT = 3; + NO_RAT_MECHANISM_MATCH_PROVER = 4; + NO_RAT_MECHANISM_MATCH_VERIFIER = 5; + RAT_PROVER_FAILED = 6; + RAT_VERIFIER_FAILED = 7; + } + + CloseCause cause_code = 1; + string cause_msg = 2; +} + +message IdscpDatExpired { //request new dynamicAttributeToken +} + +message IdscpDat { + bytes token = 1; +} + +message IdscpReRat { //request new remoteAttestatio + string cause = 1; //optional +} + +message IdscpRatProver { + bytes data = 1; +} + +message IdscpRatVerifier { + bytes data = 1; +} + +message IdscpData { + bytes data = 1 ; +} \ No newline at end of file diff --git a/idscp2/src/main/proto/tpm2dAttestation.proto b/idscp2/src/main/proto/tpm2dAttestation.proto new file mode 100644 index 000000000..74b9c3a69 --- /dev/null +++ b/idscp2/src/main/proto/tpm2dAttestation.proto @@ -0,0 +1,147 @@ +syntax = "proto2"; +option java_package = "de.fhg.aisec.ids.messages"; +option java_outer_classname = "Tpm2dAttestation"; + +// protobuf messages for communicating with TPM + +// type of attestation in the IDS context +enum IdsAttestationType { + // kernel + core container (PCR 0 to 11) + BASIC = 0; + + // everything (PCRs 0 to 23) + ALL = 1; + + // PCRs must be specified manually + ADVANCED = 2; +} + +enum HashAlgLen { + SHA1 = 20; + SHA256 = 32; + SHA384 = 48; +} + +message Pcr { + // the PCR number (usually between 0 and 23) + optional int32 number = 1; + + // the value of PCR + optional bytes value = 2; +} + +message RemoteToTpm2d { + enum Code { + ATTESTATION_REQ = 1; + } + + required Code code = 1; + + // type of attestation in the IDS context + optional IdsAttestationType atype = 2 [default = BASIC]; + + // qualifingData (i.e. external data provided by the caller, such as a nonce) + optional bytes qualifyingData = 3; + + // pcr bitmask for AttestationType ADVANCED only + // - for BASIC, the default PCRs are PCRs 0 to 11 + // - for ALL , the default PCRs are PCRs 0 to 23 + optional int32 pcrs = 4; +} + +message Tpm2dToRemote { + enum Code { + ATTESTATION_RES = 1; + } + + required Code code = 1; + + // type of attestation in the IDS context + optional IdsAttestationType atype = 2 [default = BASIC]; + + // the hash algorith used to sign the quoted information + optional HashAlgLen halg = 3; + + // the quoted information (a TPM2B_ATTEST data structure) + optional bytes quoted = 4; + + // the signature over 'quoted' (a TPMT_SIGNATURE data structure) + optional bytes signature = 5; + + // the explicit PCR values + repeated Pcr pcr_values = 6; + + // an _optional_ certificate that includes the public key + optional bytes certificate = 7; + + // the measurement list in ima style hex strings + repeated string ml_entry = 11; +} + + +// ******* Message Wrapper ******** +message Tpm2dMessageWrapper { + oneof body { + // RAT Repository + Tpm2dRepositoryRequest repositoryRequest = 1; + Tpm2dRepositoryResponse repositoryResponse = 2; + + // RAT Exchange + Tpm2dRatChallenge ratChallenge = 3; + Tpm2dRatResponse ratResponse = 4; + Tpm2dRatResult ratResult = 5; + } +} + +// ******** Rat Repository ********* +message Tpm2dRepositoryRequest { + required IdsAttestationType atype = 1; + // the explicit PCR values + repeated Pcr pcr_values = 2; +} + +message Tpm2dRepositoryResponse { + required IdsAttestationType atype = 1; + //boolean for result + required bool result = 2; +} + +// ******** RAT Exchange ********* +//Attestation Request, sent to other connector (from Verifier to Prover) +message Tpm2dRatChallenge { + required IdsAttestationType atype = 1; + // nonce for attestation request + required bytes nonce = 2; + // optional PCR indices for aType = ADVANCED + optional fixed32 pcr_indices = 3; +} + +//Attestation Response, coming from other connector (from Prover to Verifier) +message Tpm2dRatResponse { + // type of attestation in the IDS context + required IdsAttestationType atype = 1; + + // the hash algorithm used to sign the quoted information + optional string hash_alg = 2; + + // the quoted information (a TPM2B_ATTEST data structure) + required bytes quoted = 3; + + // the signature over 'quoted' (a TPMT_SIGNATURE data structure) + required bytes signature = 4; + + // the explicit PCR values + repeated Pcr pcr_values = 5; + + // AIK certificate that includes the public key + required bytes certificate = 6; + + // Measurement list + optional bytes measurement_list = 7; +} + +//Attestation Request, sent to other connector (Verifier to Prover) +message Tpm2dRatResult { + //required IdsAttestationType atype = 1; + required bool result = 1; +} \ No newline at end of file diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 62f96526d..7f9e49baa 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -1,8 +1,8 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; @@ -33,8 +33,8 @@ public void init(IDSCPv2Settings settings){ DapsDriver dapsDriver = new DefaultDapsDriver(config); - RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); - RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); + RatProverDriverRegistry.getInstance().registerDriver("TPM_2", RatProverDummy.class); + RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", RatVerifierDummy.class); IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, dapsDriver, secureChannelDriver, settings.getExpectedAttestation(), settings.getSupportedAttestation()); diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 03fc7f1b6..6557e64be 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,11 +1,10 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Prover; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2Verifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; @@ -35,8 +34,8 @@ public void init(IDSCPv2Settings serverSettings) { .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); - RatProverDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Prover.class); - RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", TPM2Verifier.class); + RatProverDriverRegistry.getInstance().registerDriver("TPM_2", RatProverDummy.class); + RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", RatVerifierDummy.class); IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, dapsDriver, secureChannelDriver, serverSettings.getExpectedAttestation(), diff --git a/idscp2/src/test/java/RatDriverTest.java b/idscp2/src/test/java/RatDriverTest.java new file mode 100644 index 000000000..4fb42c854 --- /dev/null +++ b/idscp2/src/test/java/RatDriverTest.java @@ -0,0 +1,11 @@ +import org.junit.Test; +import static org.junit.Assert.*; + +public class RatDriverTest { + + @Test + public void basisTest() { + System.out.println("Basis Test"); + assertTrue(true); + } +} From 64517bcfa555777d10745a2ce9843fb7c91ecc91 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Fri, 27 Mar 2020 15:14:30 +0100 Subject: [PATCH 056/237] WIP Implementation of TPM2d Drivers: Add configs --- idscp2/build.gradle | 15 ++-- .../rat/TPM2d/TPM2dProver.java | 21 ++++-- .../rat/TPM2d/TPM2dVerifier.java | 19 +++-- .../rat/TPM2d/Tpm2dConfig.java | 51 ------------- .../rat/TPM2d/Tpm2dProverConfig.java | 44 ++++++++++++ .../rat/TPM2d/Tpm2dVerifierConfig.java | 72 +++++++++++++++++++ .../secure_channel/client/TLSClient.java | 2 +- .../drivers/interfaces/RatProverDriver.java | 7 ++ .../drivers/interfaces/RatVerifierDriver.java | 7 ++ .../configuration/AttestationConfig.java | 2 +- .../configuration/IDSCPv2Configuration.java | 12 +++- .../idscp_core/finite_state_machine/FSM.java | 34 ++++----- .../rat_registry/RatProverDriverRegistry.java | 32 +++++++-- .../RatVerifierDriverRegistry.java | 32 +++++++-- .../src/test/java/IDSCPv2ClientInitiator.java | 30 ++++++-- .../src/test/java/IDSCPv2ServerInitiator.java | 29 ++++++-- 16 files changed, 297 insertions(+), 112 deletions(-) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java diff --git a/idscp2/build.gradle b/idscp2/build.gradle index ae7629c0f..9f543eb97 100644 --- a/idscp2/build.gradle +++ b/idscp2/build.gradle @@ -23,7 +23,7 @@ idea { } dependencies { - providedByBundle(project(':ids-api')) { transitive = false } + //providedByBundle(project(':ids-api')) { transitive = false } providedByBundle group: 'com.github.microsoft', name: 'TSS.Java', version: '0.3.0' @@ -34,21 +34,20 @@ dependencies { publishCompile group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - providedByBundle group: 'org.asynchttpclient', name: 'async-http-client', version: libraryVersions.ahc + //providedByBundle group: 'org.asynchttpclient', name: 'async-http-client', version: libraryVersions.ahc - providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-server', version: libraryVersions.jetty - providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-client', version: libraryVersions.jetty + //providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-server', version: libraryVersions.jetty + //providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-client', version: libraryVersions.jetty - testImplementation group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb - testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb - testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb + //testImplementation group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb + //testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb + //testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken providedByBundle group: 'org.json', name: 'json', version: '20180813' providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.6.5' - providedByBundle group: 'com.squareup.okhttp3', name: 'okhttp', version: libraryVersions.okhttp testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java index 4be3d812b..22890dcb2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java @@ -22,11 +22,22 @@ public class TPM2dProver extends RatProverDriver { private static final Logger LOG = LoggerFactory.getLogger(TPM2dProver.class); private BlockingQueue queue = new LinkedBlockingQueue<>(); + private Tpm2dProverConfig config = new Tpm2dProverConfig.Builder().build(); public TPM2dProver(){ super(); } + @Override + public void setConfig(Object config) { + if (config instanceof Tpm2dProverConfig) { + LOG.debug("Set rat prover config"); + this.config = (Tpm2dProverConfig) config; + } else { + LOG.warn("Invalid prover config"); + } + } + @Override public void delegate(IdscpMessage message) { queue.add(message); @@ -77,20 +88,22 @@ public void run() { Tpm2dRatChallenge challenge = tpm2dMessageWrapper.getRatChallenge(); LOG.debug("Requesting attestation from TPM ..."); - // hash //toDo add remote certificate - byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), null); + + // hash + byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), + config.getRemoteCertificate()); // generate RemoteToTPM2dRequest RemoteToTpm2d tpmRequest = TpmMessageFactory.getRemoteToTPM2dMessage( challenge.getAtype(), hash, - challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 //toDo 0 okay? + challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 ); // get TPM response Tpm2dToRemote tpmResponse; try { - TPM2dSocket tpmSocket = new TPM2dSocket(""); //toDo add host + TPM2dSocket tpmSocket = new TPM2dSocket(config.getTpm2dHost()); tpmResponse = tpmSocket.requestAttestation(tpmRequest); } catch (IOException e) { LOG.error("Cannot access TPM", e); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java index e10fcf5b6..ce6ec98fd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java @@ -34,12 +34,22 @@ public class TPM2dVerifier extends RatVerifierDriver { private static final Logger LOG = LoggerFactory.getLogger(TPM2dVerifier.class); private BlockingQueue queue = new LinkedBlockingQueue<>(); - private Tpm2dConfig config = new Tpm2dConfig.Builder().build(); + private Tpm2dVerifierConfig config = new Tpm2dVerifierConfig.Builder().build(); public TPM2dVerifier(){ super(); } + @Override + public void setConfig(Object config) { + if (config instanceof Tpm2dVerifierConfig) { + LOG.debug("Set rat verifier config"); + this.config = (Tpm2dVerifierConfig) config; + } else { + LOG.warn("Invalid config"); + } + } + @Override public void delegate(IDSCPv2.IdscpMessage message) { queue.add(message); @@ -56,7 +66,7 @@ public void run(){ // send challenge as RAT Verifier Message byte[] ratChallenge = TpmMessageFactory.getAttestationChallengeMessage( - nonce, config.getExpectedAType(), config.getAttestationMask()).toByteArray(); + nonce, config.getExpectedAType(), config.getExpectedAttestationMask()).toByteArray(); fsmListener.onRatVerifierMessage( InternalControlMessage.RAT_VERIFIER_MSG, @@ -104,9 +114,10 @@ public void run(){ Tpm2dRatResponse resp = tpm2dMessageWrapper.getRatResponse(); LOG.debug("Validate rat response: signature and rat repository checks"); - // validate signature //toDo add local certificate + + // validate signature boolean result = true; - byte[] hash = TPM2dHelper.calculateHash(nonce, null); + byte[] hash = TPM2dHelper.calculateHash(nonce, config.getLocalCertificate()); if (!checkSignature(resp, hash)) { result = false; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java deleted file mode 100644 index 84a950314..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; - -import de.fhg.aisec.ids.messages.Tpm2dAttestation.IdsAttestationType; -import java.net.URI; -import org.checkerframework.checker.nullness.qual.NonNull; - -public class Tpm2dConfig { - - private int attestationMask = 0; - @NonNull private IdsAttestationType expectedAType = IdsAttestationType.BASIC; - @NonNull private URI ttpUri = URI.create(""); - - public static class Builder { - @NonNull private Tpm2dConfig config = new Tpm2dConfig(); - - @NonNull - public Builder setAttestationMask(int attestationMask) { - config.attestationMask = attestationMask; - return this; - } - - @NonNull - public Builder setIdsAttestationType(IdsAttestationType aType) { - config.expectedAType = aType; - return this; - } - - @NonNull - public Builder setTtpUri(URI ttp) { - config.ttpUri = ttp; - return this; - } - - @NonNull - public Tpm2dConfig build() { - return config; - } - } - - public IdsAttestationType getExpectedAType() { - return expectedAType; - } - - public int getAttestationMask() { - return attestationMask; - } - - public URI getTtpUri() { - return ttpUri; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java new file mode 100644 index 000000000..2a6e10c99 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java @@ -0,0 +1,44 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import java.security.cert.Certificate; +import org.checkerframework.checker.nullness.qual.NonNull; + +public class Tpm2dProverConfig { + + private Certificate remoteCertificate; + @NonNull private String tpm2dHost; + + private Tpm2dProverConfig() { + tpm2dHost = System.getenv("TPM_HOST") != null ? + System.getenv("TPM_HOST") : "localhost"; + } + + public static class Builder { + private static Tpm2dProverConfig config = new Tpm2dProverConfig(); + + @NonNull + public Builder setRemoteCertificate(Certificate remoteCert) { + config.remoteCertificate = remoteCert; + return this; + } + + @NonNull + public Builder setTpmHost(String host) { + config.tpm2dHost = host; + return this; + } + + public Tpm2dProverConfig build() { + return config; + } + } + + public Certificate getRemoteCertificate() { + return remoteCertificate; + } + + @NonNull + public String getTpm2dHost() { + return tpm2dHost; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java new file mode 100644 index 000000000..07e8ded2e --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java @@ -0,0 +1,72 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; + +import de.fhg.aisec.ids.messages.Tpm2dAttestation.IdsAttestationType; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.cert.Certificate; +import org.checkerframework.checker.nullness.qual.NonNull; + +public class Tpm2dVerifierConfig { + + private Certificate localCertificate; + @NonNull private URI ttpUri; + @NonNull private IdsAttestationType expectedAType = IdsAttestationType.BASIC; + private int expectedAttestationMask = 0; + + private Tpm2dVerifierConfig() { + try { + ttpUri = new URI("https://invalid-ttp-uri/rat-verify"); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + public static class Builder { + private static Tpm2dVerifierConfig config = new Tpm2dVerifierConfig(); + + @NonNull + public Builder setTtpUri(URI ttpUri) { + config.ttpUri = ttpUri; + return this; + } + + @NonNull + public Builder setLocalCertificate(Certificate localCert) { + config.localCertificate = localCert; + return this; + } + + @NonNull + public Builder setExpectedAttestationType(IdsAttestationType aType) { + config.expectedAType = aType; + return this; + } + + public Builder setExpectedAttestationMask(int mask) { + config.expectedAttestationMask = mask; + return this; + } + + public Tpm2dVerifierConfig build() { + return config; + } + } + + @NonNull + public URI getTtpUri() { + return ttpUri; + } + + @NonNull + public IdsAttestationType getExpectedAType() { + return expectedAType; + } + + public Certificate getLocalCertificate() { + return localCertificate; + } + + public int getExpectedAttestationMask() { + return expectedAttestationMask; + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 1daed0d9f..e052ed7f5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -186,7 +186,7 @@ public void send(byte[] data){ out.writeInt(data.length); out.write(data); out.flush(); - LOG.debug("Send message: {}", new String(data)); + LOG.debug("Send message"); } catch (IOException e){ LOG.error("Client cannot send data"); onError(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index 7a2cefbae..fdcdc2d84 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -2,8 +2,11 @@ import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class RatProverDriver extends Thread{ + private static final Logger LOG = LoggerFactory.getLogger(RatProverDriver.class); protected boolean running = true; protected FsmListener fsmListener; @@ -19,4 +22,8 @@ public void terminate() { public void setListener(FsmListener listener){ fsmListener = listener; } + + public void setConfig(Object config){ + LOG.warn("Method 'setConfig' for RatProverDriver is not implemented"); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 73112e1b2..406748aa8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -2,8 +2,11 @@ import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import de.fhg.aisec.ids.messages.IDSCPv2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class RatVerifierDriver extends Thread{ + private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDriver.class); protected boolean running = true; protected FsmListener fsmListener; @@ -19,4 +22,8 @@ public void terminate() { public void setListener(FsmListener listener){ fsmListener = listener; } + + public void setConfig(Object config) { + LOG.warn("Method 'setConfig' for RatVerifierDriver is not implemented"); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index 42beafbbe..9c7a30457 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -12,7 +12,7 @@ public AttestationConfig(){ } public String[] getRatMechanisms(){ - return new String[] {"TPM_2", "INTEL_SGX", "ARM_TRUST_ZONE"}; + return new String[] {"Dummy", "TPM2d"}; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index a93cbed43..8b04db0df 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -33,18 +33,22 @@ public class IDSCPv2Configuration implements IDSCPv2Callback { private SecureChannelDriver secureChannelDriver; private final String[] localExpectedRatCipher; private final String[] localSupportedRatCipher; + private int ratTimeout; public IDSCPv2Configuration(IDSCPv2Initiator initiator, DapsDriver dapsDriver, SecureChannelDriver secureChannelDriver, AttestationConfig expectedAttestation, - AttestationConfig supportedAttestation){ + AttestationConfig supportedAttestation, + int ratTimeout + ){ this.user = initiator; this.dapsDriver = dapsDriver; this.secureChannelDriver = secureChannelDriver; this.localExpectedRatCipher = expectedAttestation.getRatMechanisms(); this.localSupportedRatCipher = supportedAttestation.getRatMechanisms(); + this.ratTimeout = ratTimeout; } public void connect(IDSCPv2Settings settings){ @@ -73,7 +77,8 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, localExpectedRatCipher); + FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, + localExpectedRatCipher, ratTimeout); try { fsm.startIdscpHandshake(); //blocking until handshake is done @@ -93,7 +98,8 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, localExpectedRatCipher); + FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, + localExpectedRatCipher, ratTimeout); try { fsm.startIdscpHandshake(); //blocking until handshake is done diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index e510564fa..10869cc85 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -58,10 +58,9 @@ enum FSM_STATE { private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; - private final int ratTimeoutDelay = 20; public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, - String[] localSupportedRatSuite, String[] localExpectedRatSuite){ + String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout){ this.secureChannel = secureChannel; secureChannel.setFsm(this); @@ -83,7 +82,6 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, onControlMessage(InternalControlMessage.REPEAT_RAT); }; - //toDo set correct delays this.handshakeTimer = new Timer(fsmIsBusy, handshakeTimeoutHandler); this.datTimer = new Timer(fsmIsBusy, datTimeoutHandler); this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); @@ -94,11 +92,11 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, states.put(FSM_STATE.STATE_WAIT_FOR_HELLO, new StateWaitForHello(this, handshakeTimer, datTimer, dapsDriver, localSupportedRatSuite, localExpectedRatSuite)); states.put(FSM_STATE.STATE_WAIT_FOR_RAT, new StateWaitForRat(this, handshakeTimer, ratTimer, - ratTimeoutDelay, dapsDriver)); + ratTimeout, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_RAT_PROVER, new StateWaitForRatProver(this, ratTimer, handshakeTimer, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER, new StateWaitForRatVerifier(this, dapsDriver, ratTimer, - handshakeTimer, ratTimeoutDelay)); + handshakeTimer, ratTimeout)); states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT, new StateWaitForDatAndRat(this, handshakeTimer, datTimer, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, new StateWaitForDatAndRatVerifier(this, @@ -294,13 +292,13 @@ void notifyHandshakeCompleteLock(){ //calculate Prover mechanism (strongest remote expected), returns null if no match was found String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ //toDo implement logic - return "TPM_2"; + return localSupportedProver[0]; } //calculate Verifier mechanism (strongest local expected), returns null if no match was found String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ //toDo implement logic - return "TPM_2"; + return localExpectedVerifier[0]; } void restartRatVerifierDriver(){ @@ -355,16 +353,18 @@ State getState(FSM_STATE state){ } void lockFsm(){ - secureChannel.close(); - this.datTimer.cancelTimeout(); - this.datTimer = null; - this.ratTimer.cancelTimeout(); - this.ratTimer = null; - this.handshakeTimer.cancelTimeout(); - this.handshakeTimer = null; - this.stopRatProverDriver(); - this.stopRatVerifierDriver(); - fsmIsClosed = true; + try { + secureChannel.close(); + this.datTimer.cancelTimeout(); + this.datTimer = null; + this.ratTimer.cancelTimeout(); + this.ratTimer = null; + this.handshakeTimer.cancelTimeout(); + this.handshakeTimer = null; + this.stopRatProverDriver(); + this.stopRatVerifierDriver(); + fsmIsClosed = true; + } catch (NullPointerException ignored){} //inform upper layer via handshake or closeListener try { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java index 708c2f6f1..d18a74807 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -6,9 +6,9 @@ import java.util.concurrent.ConcurrentHashMap; public class RatProverDriverRegistry { - //toDO Reflections library + //toDo Reflections library private static RatProverDriverRegistry instance; - private static ConcurrentHashMap> drivers = new ConcurrentHashMap<>(); + private static ConcurrentHashMap drivers = new ConcurrentHashMap<>(); private RatProverDriverRegistry(){} @@ -21,11 +21,14 @@ public static RatProverDriverRegistry getInstance(){ } public static RatProverDriver startRatProverDriver(String instance, FsmListener listener){ - Class driverClass = drivers.get(instance); + DriverWrapper driverWrapper = drivers.get(instance); try { - RatProverDriver driver = driverClass.getDeclaredConstructor().newInstance(); + RatProverDriver driver = driverWrapper.driverClass.getDeclaredConstructor().newInstance(); driver.setListener(listener); + if (driverWrapper.driverConfig != null) { + driver.setConfig(driverWrapper.driverConfig); + } driver.start(); return driver; @@ -35,12 +38,29 @@ public static RatProverDriver startRatProverDriver(String instance, FsmListener } - public void registerDriver(String instance, Class driverClass){ - drivers.put(instance, driverClass); + public void registerDriver( + String instance, + Class driverClass, + Object driverConfig + ){ + drivers.put(instance, new DriverWrapper(driverClass, driverConfig)); } public void unregisterDriver(String instance){ drivers.remove(instance); } + private static class DriverWrapper { + private Class driverClass; + private Object driverConfig; + + private DriverWrapper( + Class driverClass, + Object driverConfig + ) { + this.driverClass = driverClass; + this.driverConfig = driverConfig; + } + } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java index cb1536292..4b32fc5f6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java @@ -8,7 +8,8 @@ public class RatVerifierDriverRegistry { private static RatVerifierDriverRegistry instance; - private static ConcurrentHashMap> drivers = new ConcurrentHashMap<>(); + private static ConcurrentHashMap drivers + = new ConcurrentHashMap<>(); private RatVerifierDriverRegistry(){} @@ -16,16 +17,18 @@ public static RatVerifierDriverRegistry getInstance(){ if (instance == null){ instance = new RatVerifierDriverRegistry(); } - return instance; } public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmListener listener){ - Class driverClass = drivers.get(mechanism); + DriverWrapper driverWrapper = drivers.get(mechanism); try { - RatVerifierDriver driver = driverClass.getDeclaredConstructor().newInstance(); + RatVerifierDriver driver = driverWrapper.driverClass.getDeclaredConstructor().newInstance(); driver.setListener(listener); + if (driverWrapper.driverConfig != null) { + driver.setConfig(driverWrapper.driverConfig); + } driver.start(); return driver; @@ -34,13 +37,28 @@ public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmList } } - - public void registerDriver(String mechanism, Class driverClass){ - drivers.put(mechanism, driverClass); + public void registerDriver( + String mechanism, + Class driverClass, + Object driverConfig + ){ + drivers.put(mechanism, new DriverWrapper(driverClass, driverConfig)); } public void unregisterDriver(String instance){ drivers.remove(instance); } + private static class DriverWrapper { + private Class driverClass; + private Object driverConfig; + + private DriverWrapper( + Class driver, + Object driverConfig + ) { + this.driverClass = driver; + this.driverConfig = driverConfig; + } + } } diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 7f9e49baa..924f646c2 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -1,6 +1,10 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dProver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dVerifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dProverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; @@ -33,15 +37,31 @@ public void init(IDSCPv2Settings settings){ DapsDriver dapsDriver = new DefaultDapsDriver(config); - RatProverDriverRegistry.getInstance().registerDriver("TPM_2", RatProverDummy.class); - RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", RatVerifierDummy.class); + RatProverDriverRegistry.getInstance().registerDriver( + "Dummy", RatProverDummy.class, null); + RatVerifierDriverRegistry.getInstance().registerDriver( + "Dummy", RatVerifierDummy.class, null); - IDSCPv2Configuration clientConfig = new IDSCPv2Configuration(this, - dapsDriver, secureChannelDriver, settings.getExpectedAttestation(), settings.getSupportedAttestation()); + RatProverDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dProver.class, + new Tpm2dProverConfig.Builder().build() + ); + RatVerifierDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dVerifier.class, + new Tpm2dVerifierConfig.Builder().build() + ); + + IDSCPv2Configuration clientConfig = new IDSCPv2Configuration( + this, + dapsDriver, + secureChannelDriver, + settings.getExpectedAttestation(), + settings.getSupportedAttestation(), + 20 + ); clientConfig.connect(settings); } - @Override public void newConnectionHandler(IDSCPv2Connection connection) { this.connections.put(connection.getConnectionId(), connection); diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 6557e64be..eeefaa987 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -1,6 +1,10 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dProver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dVerifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dProverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; @@ -34,12 +38,27 @@ public void init(IDSCPv2Settings serverSettings) { .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); - RatProverDriverRegistry.getInstance().registerDriver("TPM_2", RatProverDummy.class); - RatVerifierDriverRegistry.getInstance().registerDriver("TPM_2", RatVerifierDummy.class); + RatProverDriverRegistry.getInstance().registerDriver( + "Dummy", RatProverDummy.class, null); + RatVerifierDriverRegistry.getInstance().registerDriver( + "Dummy", RatVerifierDummy.class, null); + RatProverDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dProver.class, + new Tpm2dProverConfig.Builder().build() + ); + RatVerifierDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dVerifier.class, + new Tpm2dVerifierConfig.Builder().build() + ); + + IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration( + this, + dapsDriver, + secureChannelDriver, + serverSettings.getExpectedAttestation(), + serverSettings.getSupportedAttestation(), + 20); - IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration(this, - dapsDriver, secureChannelDriver, serverSettings.getExpectedAttestation(), - serverSettings.getSupportedAttestation()); IDSCPv2Server idscPv2Server; try { idscPv2Server = idscpServerConfig.listen(serverSettings); From 3c1a383a69a49d2caa45827077fbd1b45b684cdc Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Fri, 27 Mar 2020 21:30:35 +0100 Subject: [PATCH 057/237] Fix bugs in FSM: Avoid thread circles, that could produce undefined behaviour --- idscp2/README.md | 2 +- .../rat/dummy/RatProverDummy.java | 2 +- .../rat/dummy/RatVerifierDummy.java | 2 +- .../secure_channel/client/TLSClient.java | 8 +- .../server/TLSServerThread.java | 11 ++- .../configuration/IDSCPv2Settings.java | 10 +++ .../idscp_core/finite_state_machine/FSM.java | 84 ++++++++++++++++--- .../finite_state_machine/FsmListener.java | 1 - .../finite_state_machine/StateClosed.java | 9 +- .../StateEstablished.java | 37 ++++++-- .../StateWaitForDatAndRat.java | 34 ++++++-- .../StateWaitForDatAndRatVerifier.java | 23 ++++- .../StateWaitForHello.java | 13 ++- .../finite_state_machine/StateWaitForRat.java | 36 ++++++-- .../StateWaitForRatProver.java | 46 ++++++++-- .../StateWaitForRatVerifier.java | 33 ++++++-- .../rat_registry/RatProverDriverRegistry.java | 1 - .../secure_channel/SecureChannel.java | 4 +- .../secure_channel/SecureChannelEndpoint.java | 2 +- .../src/test/java/IDSCPv2ClientInitiator.java | 2 +- .../src/test/java/IDSCPv2ServerInitiator.java | 3 +- idscp2/src/test/java/RunTLSClient.java | 1 + idscp2/src/test/java/RunTLSServer.java | 1 + 23 files changed, 301 insertions(+), 64 deletions(-) diff --git a/idscp2/README.md b/idscp2/README.md index 990171e66..9874e883f 100644 --- a/idscp2/README.md +++ b/idscp2/README.md @@ -1 +1 @@ -The _ids-comm_ module wraps the IDSCP, providing secure communication and remote attestation between Connector instances. +The _idscp2_ implements the second version of the IDS Communication Protocol diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 90a8786a3..276f75804 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -32,7 +32,7 @@ public void delegate(IdscpMessage message) { @Override public void run() { int countDown = 2; - while (true){ + while (running){ try { sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index dacda0537..879223b3c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -28,7 +28,7 @@ public void delegate(IDSCPv2.IdscpMessage message) { @Override public void run(){ int countDown = 2; - while (true){ + while (running){ try { sleep(1000); LOG.debug("Verifier waits"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index e052ed7f5..93c85f7a0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -177,19 +177,21 @@ public void close() { disconnect(); } - public void send(byte[] data){ + @Override + public boolean send(byte[] data){ if (!isConnected()){ LOG.error("Client cannot send data because socket is not connected"); - onError(); + return false; } else { try { out.writeInt(data.length); out.write(data); out.flush(); LOG.debug("Send message"); + return true; } catch (IOException e){ LOG.error("Client cannot send data"); - onError(); + return false; } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 0aa00b7f8..e70f124d3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -84,6 +84,7 @@ public void run(){ //timeout catches safeStop() call and allows to send server_goodbye //alternative: close sslSocket and catch SocketException //continue + } catch (EOFException e){ onClose(); running = false; @@ -108,21 +109,23 @@ private void closeSockets(){ } } - public void send(byte[] data) { + @Override + public boolean send(byte[] data) { if (!isConnected()){ LOG.error("Server cannot send data because socket is not connected"); closeSockets(); - onError(); + return false; } else { try { out.writeInt(data.length); out.write(data); out.flush(); - LOG.trace("Send message: " + new String(data)); + LOG.debug("Send message: " + new String(data)); + return true; } catch (IOException e){ LOG.error("ServerThread cannot send data."); closeSockets(); - onError(); + return false; } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index d427fc296..554764686 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -22,6 +22,7 @@ public class IDSCPv2Settings { private String keyStoreKeyType = "RSA"; private AttestationConfig supportedAttestation = new AttestationConfig(); private AttestationConfig expectedAttestation = new AttestationConfig(); + private int ratTimeoutDelay = 20; public static class Builder { @NonNull @@ -87,6 +88,11 @@ public Builder setExpectedAttestationSuite(AttestationConfig suite) { return this; } + public Builder setRatTimeoutDelay(int delay) { + this.settings.ratTimeoutDelay = delay; + return this; + } + @NonNull public IDSCPv2Settings build() { return this.settings; @@ -137,4 +143,8 @@ public String getDapsKeyAlias() { public String getHost() { return host; } + + public int getRatTimeoutDelay() { + return ratTimeoutDelay; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 10869cc85..e076095cc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -108,8 +108,38 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, currentState = states.get(FSM_STATE.STATE_CLOSED); } + private void checkForFsmCircles() { + + // check if current thread holds already the fsm lock, then we have a circle + // this runs into an issue: onControlMessage must be called only from other threads! + // if the current thread currently stuck within a fsm transition it will trigger another + // transition on the old state and undefined behaviour occurred + // + // The idscpv2 core and default driver will not run into this issue. It's a protection for + // avoiding incorrect usage of the idscpv2 library from further driver implementations + // + // Example: + // Thread A stuck within a transition t1 that calls a function that calls + // onControlMessage(InternalError). Then the error is handled in the current state + // state and the fsm will switch into state STATE_CLOSED and close all resources. + // + // Afterwards, the thread will continue the old transition t1 that might use some of the + // closed resources and switch in a non-closed STATE, e.g. STATE_ESTABLISHED. + // So our fsm would be broken and the behaviour is undefined and could leak security + // vulnerabilities + // + if (fsmIsBusy.isHeldByCurrentThread()) { + throw new RuntimeException("The current thread holds the fsm lock already. " + + "A circle might occur that could lead to undefined behaviour within the fsm"); + } + } + @Override public void onMessage(byte[] data){ + + //check for incorrect usage + checkForFsmCircles(); + //parse message and create new IDSCP Message Event, then pass it to current state and update new state IdscpMessage message; try { @@ -124,6 +154,11 @@ public void onMessage(byte[] data){ fsmIsBusy.lock(); try { while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))){ + + if (fsmIsClosed) { + return; + } + try { onMessageBlock.await(); } catch (InterruptedException e) { @@ -137,8 +172,7 @@ public void onMessage(byte[] data){ } - @Override - public void onControlMessage(InternalControlMessage controlMessage) { + private void onControlMessage(InternalControlMessage controlMessage) { //create Internal Control Message Event and pass it to current state and update new state Event e = new Event(controlMessage); @@ -152,6 +186,10 @@ public void onControlMessage(InternalControlMessage controlMessage) { @Override public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + + //check for incorrect usage + checkForFsmCircles(); + //only allow rat prover messages from current thread Event e; if (idscpMessage == null){ @@ -174,6 +212,10 @@ public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessa @Override public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + + //check for incorrect usage + checkForFsmCircles(); + //only allow rat verifier messages from current thread Event e; if (idscpMessage == null){ @@ -204,6 +246,10 @@ private void feedEvent(Event event){ } public void terminate(){ + + //check for incorrect usage + checkForFsmCircles(); + LOG.info("Close idscp connection"); onControlMessage(InternalControlMessage.IDSCP_STOP); LOG.debug("Close secure channel"); @@ -211,6 +257,10 @@ public void terminate(){ } public void startIdscpHandshake() throws IDSCPv2Exception { + + //check for incorrect usage + checkForFsmCircles(); + fsmIsBusy.lock(); try { if (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { @@ -241,18 +291,26 @@ public void startIdscpHandshake() throws IDSCPv2Exception { } } - void sendFromFSM(IdscpMessage msg){ + boolean sendFromFSM(IdscpMessage msg){ //send messages from fsm - secureChannel.send(msg.toByteArray()); + return secureChannel.send(msg.toByteArray()); } @Override public void onError(){ + + //check for incorrect usage + checkForFsmCircles(); + onControlMessage(InternalControlMessage.ERROR); } @Override public void onClose(){ + + //check for incorrect usage + checkForFsmCircles(); + onControlMessage(InternalControlMessage.ERROR); } @@ -261,7 +319,10 @@ public void send(IdscpMessage msg){ fsmIsBusy.lock(); try{ if(isConnected()){ - secureChannel.send(msg.toByteArray()); + if (!secureChannel.send(msg.toByteArray())) { + LOG.error("Cannot send IDSCP_DATA via secure channel"); + onControlMessage(InternalControlMessage.ERROR); + } } else { LOG.error("Cannot send IDSCP_DATA because protocol is not established"); } @@ -301,16 +362,17 @@ String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSu return localExpectedVerifier[0]; } - void restartRatVerifierDriver(){ + boolean restartRatVerifierDriver(){ //assume verifier mechanism is set stopRatVerifierDriver(); ratVerifierDriver = RatVerifierDriverRegistry.startRatVerifierDriver(verifierMechanism, this); if (ratVerifierDriver == null){ LOG.error("Cannot create instance of RAT_VERIFIER_DRIVER"); currentRatVerifierId = ""; - onControlMessage(InternalControlMessage.ERROR); //toDo geht das? nein + return false; } else { currentRatVerifierId = Long.toString(ratVerifierDriver.getId()); + return true; } } @@ -321,16 +383,18 @@ void stopRatVerifierDriver(){ } } - void restartRatProverDriver(){ + + boolean restartRatProverDriver(){ //assume prover mechanism is set stopRatProverDriver(); ratProverDriver = RatProverDriverRegistry.startRatProverDriver(proverMechanism, this); if (ratProverDriver == null){ LOG.error("Cannot create instance of RAT_PROVER_DRIVER"); currentRatProverId = ""; - onControlMessage(InternalControlMessage.ERROR); //toDo geht das? nein + return false; } else { currentRatProverId = Long.toString(ratProverDriver.getId()); + return true; } } @@ -366,7 +430,7 @@ void lockFsm(){ fsmIsClosed = true; } catch (NullPointerException ignored){} - //inform upper layer via handshake or closeListener + //notify upper layer via handshake or closeListener try { if (handshakeResultAvailable){ listenerLatch.await(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index 0a2dc0659..dc651ed0a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -4,7 +4,6 @@ public interface FsmListener { void onMessage(byte[] data); - void onControlMessage(InternalControlMessage controlMessage); void onRatProverMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); void onRatVerifierMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); void onError(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 2d553b8e0..5b10bbd33 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -3,6 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +36,13 @@ public StateClosed(FSM fsm, LOG.debug("Send IDSCP_HELLO"); IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. getIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); - fsm.sendFromFSM(idscpHello); + + if (!fsm.sendFromFSM(idscpHello)) { + LOG.error("Cannot send IdscpHello. Close connection"); + runEntryCode(fsm); + onMessageLock.notifyAll(); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } runExitCode(onMessageLock); return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_HELLO); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index bec092246..eb21ca622 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,8 +50,16 @@ public StateEstablished(FSM fsm, event -> { LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); ratTimer.cancelTimeout(); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); - fsm.restartRatVerifierDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage(""))) { + LOG.error("Cannot send ReRat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatVerifierDriver()) { + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); @@ -63,7 +72,10 @@ public StateEstablished(FSM fsm, event -> { ratTimer.cancelTimeout(); LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -71,7 +83,12 @@ public StateEstablished(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); - fsm.restartRatProverDriver(); + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); } )); @@ -79,8 +96,16 @@ public StateEstablished(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send Dat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index e0336ed01..139342778 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +39,7 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -80,7 +81,10 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - fsm.sendFromFSM(event.getIdscpMessage()); + if (!fsm.sendFromFSM(event.getIdscpMessage())) { + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return this; } )); @@ -101,14 +105,18 @@ public StateWaitForDatAndRat(FSM fsm, long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage( + "No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } LOG.debug("Remote DAT is valid. Set dat timeout"); datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier - fsm.restartRatVerifierDriver(); + if (!fsm.restartRatVerifierDriver()) { + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } @@ -117,8 +125,17 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send Dat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return this; } )); @@ -134,7 +151,10 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - fsm.restartRatProverDriver(); + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 1118112c8..fae2289f9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,7 +78,10 @@ public StateWaitForDatAndRatVerifier(FSM fsm, LOG.debug("Remote DAT is valid. Set dat timeout"); datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier - fsm.restartRatVerifierDriver(); + if (!fsm.restartRatVerifierDriver()) { + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); @@ -89,8 +93,16 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); @@ -98,7 +110,10 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - fsm.restartRatProverDriver(); + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index 323155f3e..7f583002b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -3,6 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,8 +111,16 @@ public StateWaitForHello(FSM fsm, fsm.setRatMechanisms(proverMechanism, verifierMechanism); LOG.debug("Start RAT Prover and Verifier"); - fsm.restartRatVerifierDriver(); - fsm.restartRatProverDriver(); + + if (!fsm.restartRatVerifierDriver()) { + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index 7cb3bb4e1..82a599fe2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,7 +94,12 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - fsm.sendFromFSM(event.getIdscpMessage()); + + if (!fsm.sendFromFSM(event.getIdscpMessage())) { + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return this; } )); @@ -101,7 +107,12 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_VERIFIER"); - fsm.sendFromFSM(event.getIdscpMessage()); + + if (!fsm.sendFromFSM(event.getIdscpMessage())) { + LOG.error("Cannot send rat verifier message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return this; } )); @@ -110,7 +121,12 @@ public StateWaitForRat(FSM fsm, event -> { LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); @@ -143,10 +159,20 @@ public StateWaitForRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); + return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index bad5b19a7..0b7470f2c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +61,12 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); ratTimer.cancelTimeout(); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); @@ -86,7 +92,12 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_PROVER"); - fsm.sendFromFSM(event.getIdscpMessage()); + + if (!fsm.sendFromFSM(event.getIdscpMessage())) { + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return this; } )); @@ -94,9 +105,19 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.REPEAT_RAT.getValue(), new Transition( event -> { LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage("")); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage(""))) { + LOG.error("Cannot send ReRat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + ratTimer.cancelTimeout(); - fsm.restartRatVerifierDriver(); + + if (!fsm.restartRatVerifierDriver()) { + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } )); @@ -111,8 +132,16 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } LOG.debug("Set handshake timeout"); handshakeTimer.resetTimeout(5); return this; @@ -130,7 +159,10 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); - fsm.restartRatProverDriver(); + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 59c1ee108..e021d67e4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +60,12 @@ public StateWaitForRatVerifier(FSM fsm, event -> { LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage()); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -87,7 +93,12 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.RAT_VERIFIER_MSG.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_RAT_VERIFIER"); - fsm.sendFromFSM(event.getIdscpMessage()); + + if (!fsm.sendFromFSM(event.getIdscpMessage())) { + LOG.error("Cannot send rat verifier message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return this; } )); @@ -102,8 +113,17 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken())); - fsm.restartRatProverDriver(); + + if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } )); @@ -119,7 +139,10 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); - fsm.restartRatProverDriver(); + if (!fsm.restartRatProverDriver()) { + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); + } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java index d18a74807..703300b06 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -6,7 +6,6 @@ import java.util.concurrent.ConcurrentHashMap; public class RatProverDriverRegistry { - //toDo Reflections library private static RatProverDriverRegistry instance; private static ConcurrentHashMap drivers = new ConcurrentHashMap<>(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index 73e90f072..e105a5cdf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -36,9 +36,9 @@ public void close(){ endpoint.close(); } - public void send(byte[] msg){ + public boolean send(byte[] msg){ LOG.debug("Send message via secure channel"); - endpoint.send(msg); + return endpoint.send(msg); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index f3134434c..a4a2390ab 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -16,6 +16,6 @@ public interface SecureChannelEndpoint { void close(); void onMessage(byte[] bytes); - void send(byte[] bytes); + boolean send(byte[] bytes); boolean isConnected(); } diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 924f646c2..8e49a7a44 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -57,7 +57,7 @@ public void init(IDSCPv2Settings settings){ secureChannelDriver, settings.getExpectedAttestation(), settings.getSupportedAttestation(), - 20 + settings.getRatTimeoutDelay() ); clientConfig.connect(settings); } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index eeefaa987..9c1a9802b 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -57,7 +57,8 @@ public void init(IDSCPv2Settings serverSettings) { secureChannelDriver, serverSettings.getExpectedAttestation(), serverSettings.getSupportedAttestation(), - 20); + serverSettings.getRatTimeoutDelay() + ); IDSCPv2Server idscPv2Server; try { diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/test/java/RunTLSClient.java index 87500b62c..1e0983803 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/test/java/RunTLSClient.java @@ -12,6 +12,7 @@ public static void main(String[] args){ getResource("ssl/client-truststore_new.jks").getPath()) .setCertificateAlias("1.0.1") .setDapsKeyAlias("1") + .setRatTimeoutDelay(10) .build(); IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/test/java/RunTLSServer.java index e2f9e4f91..1635158b8 100644 --- a/idscp2/src/test/java/RunTLSServer.java +++ b/idscp2/src/test/java/RunTLSServer.java @@ -11,6 +11,7 @@ public static void main(String[] argv){ getResource("ssl/client-truststore_new.jks").getPath()) .setCertificateAlias("1.0.1") .setDapsKeyAlias("1") + .setRatTimeoutDelay(14) .build(); IDSCPv2ServerInitiator initiator = new IDSCPv2ServerInitiator(); From 48cedda143e887c026b84be7e70f097be41a70d5 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Sat, 28 Mar 2020 07:55:56 +0100 Subject: [PATCH 058/237] Fix potential issue with uncatched expections during tls handshake on tlsServerThread --- .../keystores/PreConfiguration.java | 2 +- .../rat/TPM2d/TpmMessageFactory.java | 5 ++--- .../client/InputListenerThread.java | 10 ++++----- .../server/TLSServerThread.java | 21 ++++++++++++------- .../StateEstablished.java | 2 +- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index cc8b465a1..d218c6e56 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -44,7 +44,7 @@ public static TrustManager[] getX509ExtTrustManager( //allow only X509 Authentication if (myTrustManager.length == 1 && myTrustManager[0] instanceof X509ExtendedTrustManager) { //toDo algorithm constraints - //toDo hostname verification is currently done by using https identification protocol + //hostname verification is currently done by using https identification protocol return myTrustManager; } else { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(myTrustManager)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java index 1379fdbec..6c7818e58 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java @@ -69,7 +69,7 @@ static Tpm2dMessageWrapper getAttestationResultMessage( ).build(); } - static Tpm2dMessageWrapper getAttestationRepositoryRequestMessage( + /*static Tpm2dMessageWrapper getAttestationRepositoryRequestMessage( IdsAttestationType aType, List pcrValues ) { @@ -84,10 +84,9 @@ static Tpm2dMessageWrapper getAttestationRepositoryRequestMessage( static Tpm2dMessageWrapper getAttestationRepositoryResponseMessage() { return Tpm2dMessageWrapper.newBuilder().setRepositoryResponse( Tpm2dRepositoryResponse.newBuilder() - //toDo add values .build() ).build(); - } + }*/ static RemoteToTpm2d getRemoteToTPM2dMessage( IdsAttestationType aType, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 8d49dc954..1c9f7400c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -40,11 +40,9 @@ public void run(){ buf = new byte[len]; in.readFully(buf, 0, len); this.listener.onMessage(buf); - } catch (SocketTimeoutException e) { - //timeout to catch safeStop() call, which allows save close and sending Client_Goodbye - //alternative: close socket / InputStream and catch exception - //continue; - //toDo offset when timeout while reading ??? + } catch (SocketTimeoutException ignore) { + //timeout to catch safeStop() call + //alternative: close socket / InputStream and catch exception SocketException } catch (EOFException e){ listener.onClose(); @@ -61,7 +59,7 @@ public void register(DataAvailableListener listener) { this.listener = listener; } - + @Override public void safeStop() { this.running = false; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index e70f124d3..2aaecad0d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -71,6 +71,16 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene @Override public void run(){ + // first run the tls handshake to enforce catching every error occurred during the handshake + // before reading from buffer. Else if there exists any non-catched exception during handshake + // the thread would wait forever in onError() until handshakeCompleteListener is called + try { + sslSocket.startHandshake(); + } catch (IOException e) { + LOG.warn("SSLHandshakeException occurred. Quit server session"); + running = false; + } + //wait for new data while running byte[] buf; while (running){ @@ -80,7 +90,7 @@ public void run(){ in.readFully(buf, 0, len); onMessage(buf); - } catch (SocketTimeoutException e){ + } catch (SocketTimeoutException e) { //timeout catches safeStop() call and allows to send server_goodbye //alternative: close sslSocket and catch SocketException //continue @@ -88,11 +98,8 @@ public void run(){ } catch (EOFException e){ onClose(); running = false; - } catch (SSLHandshakeException e) { - LOG.warn("SSLHandshakeException occurred. Quit server session"); - running = false; } catch (IOException e){ - onError(); //FIXME ??? is there any other exception that could occur before fsm was created ??, if so -> Thread will run forever + onError(); running = false; } } @@ -104,9 +111,7 @@ private void closeSockets(){ out.close(); in.close(); sslSocket.close(); - } catch (IOException e) { - //e.printStackTrace(); - } + } catch (IOException ignore) {} } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index eb21ca622..4db494542 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -22,7 +22,7 @@ public StateEstablished(FSM fsm, * onICM: error ---> {timeouts.cancel(), send IDSCP_CLOSE} ---> STATE_CLOSED * onICM: stop ---> {timeouts.cancel()} ---> STATE_CLOSED * onICM: re_rat ---> {send IDSCP_RE_RAT, start RAT_VERIFIER} ---> STATE_WAIT_FOR_RAT_VERIFIER - * //FIXME onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED + * //onICM: send_data ---> {send IDS_DATA} ---> STATE_ESTABLISHED * onICM: dat_timeout ---> {send IDSCP_DAT_EXPIRED} ---> STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER * onMessage: IDSCP_DATA ---> {delegate to connection} ---> STATE_ESTABLISHED * onMessage: IDSCP_RERAT ---> {start RAT_PROVER} ---> STATE_WAIT_FOR_RAT_PROVER From 692fdef7eb83378d98bec9b5dfa33f8e3de8cbc4 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Sat, 28 Mar 2020 21:40:53 +0100 Subject: [PATCH 059/237] Upgrade TLS security: add hostname verification and certificate validation --- idscp2/build.gradle | 11 -- .../CustomX509ExtendedKeyManager.java | 41 ++++--- .../CustomX509ExtendedTrustManager.java | 79 ------------- .../keystores/PreConfiguration.java | 23 +++- .../TlsSessionVerificationHelper.java | 110 ++++++++++++++++++ .../client/InputListenerThread.java | 9 +- .../secure_channel/client/TLSClient.java | 23 ++-- .../secure_channel/server/TLSServer.java | 3 - .../server/TLSServerThread.java | 39 +++++-- .../idscp_core/finite_state_machine/FSM.java | 6 +- .../finite_state_machine/StateClosed.java | 2 +- 11 files changed, 207 insertions(+), 139 deletions(-) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java diff --git a/idscp2/build.gradle b/idscp2/build.gradle index 9f543eb97..81df80963 100644 --- a/idscp2/build.gradle +++ b/idscp2/build.gradle @@ -23,8 +23,6 @@ idea { } dependencies { - //providedByBundle(project(':ids-api')) { transitive = false } - providedByBundle group: 'com.github.microsoft', name: 'TSS.Java', version: '0.3.0' providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j @@ -34,15 +32,6 @@ dependencies { publishCompile group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - //providedByBundle group: 'org.asynchttpclient', name: 'async-http-client', version: libraryVersions.ahc - - //providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-server', version: libraryVersions.jetty - //providedByFeature group: 'org.eclipse.jetty.websocket', name: 'websocket-client', version: libraryVersions.jetty - - //testImplementation group: "javax.xml.bind", name: "jaxb-api", version: libraryVersions.jaxb - //testImplementation group: "com.sun.xml.bind", name: "jaxb-core", version: libraryVersions.jaxb - //testImplementation group: "com.sun.xml.bind", name: "jaxb-impl", version: libraryVersions.jaxb - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index 56f3591a7..0719a7783 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -40,10 +40,10 @@ public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ } @Override - public String[] getClientAliases(String s, Principal[] principals) { - String[] clientAliases = delegate.getClientAliases(s, principals); + public String[] getClientAliases(String keyType, Principal[] issuers) { + String[] clientAliases = delegate.getClientAliases(keyType, issuers); for (String alias : clientAliases) - cachedAliases.putIfAbsent(alias, new CachedAliasValue(s, principals)); + cachedAliases.putIfAbsent(alias, new CachedAliasValue(keyType, null)); //toDo get issuer return clientAliases; } @@ -54,7 +54,7 @@ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket s if (Arrays.asList(keyTypes).contains(this.keyType)){ if ((cachedAliases.containsKey(this.certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) - || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { + || Arrays.asList(getClientAliases(keyType, issuers)).contains(this.certAlias)) { LOG.debug("CertificateAlias is {}", this.certAlias); return this.certAlias; } else { @@ -70,10 +70,10 @@ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket s } @Override - public String[] getServerAliases(String s, Principal[] principals) { - String[] serverAliases = delegate.getServerAliases(s, principals); + public String[] getServerAliases(String keyType, Principal[] issuers) { + String[] serverAliases = delegate.getServerAliases(keyType, issuers); for (String alias : serverAliases) - cachedAliases.putIfAbsent(alias, new CachedAliasValue(s, principals)); + cachedAliases.putIfAbsent(alias, new CachedAliasValue(keyType, null)); //toDo get issuer return serverAliases; } @@ -135,17 +135,30 @@ public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEn return delegate.chooseEngineServerAlias(keyType, issuers, sslEngine); } - private class CachedAliasValue { - private String keyType; - private Principal[] issuers; - CachedAliasValue(String keyType, Principal[] issuers){ + private static class CachedAliasValue { + private String keyType; //key algorithm type name + private Principal issuer; //certificate issuer + + CachedAliasValue(String keyType, Principal issuer){ this.keyType = keyType; - this.issuers = issuers; + this.issuer = issuer; } - boolean match(String keyType, Principal[] principals){ - return this.keyType.equals(keyType) && (principals == null /* || //FIXME check issuers */); + /* + * This method is called for a given certificate alias and checks if the corresponding + * cached alias entry (contains keytype for certAlias and issuer of thee certificate) + * matches the requested conditions in thee TLS handshake. + * + * It must enforce checking if the certAlias belongs to a valid key algorithm type name, + * e.g. 'RSA' or 'EC' and it must check if the certificate issuer is one of the accepted + * issuer from the given principals list. + * + * returns true, if the keyAlias fulfills the requirements + */ + boolean match(String keyType, Principal[] issuers){ + return this.keyType.equals(keyType) && (issuers == null + || Arrays.asList(issuers).contains(issuer)); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java deleted file mode 100644 index b3d06200e..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedTrustManager.java +++ /dev/null @@ -1,79 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.X509ExtendedTrustManager; -import java.net.Socket; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -/** - * currently not in use, we will use the https hostname verification instead - * - * A custom X509ExtendedTrustManager for hostname verification and algorithm constraints, - * which is an application protocol task and avoids Man-In-The-Middle Attacks - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class CustomX509ExtendedTrustManager extends X509ExtendedTrustManager { - /* - * verifying that the certificate itself can be trusted (RFC 3280/5280) and verifying the identity in the certificate (RFC 6125, or RFC 2818 for HTTPS) - * https://tersesystems.com/blog/2014/03/23/fixing-hostname-verification/ - * https://tools.ietf.org/html/rfc6125 - * https://tools.ietf.org/search/rfc6125 - * - * - * sslParams.setEndpointIdentificationAlgorithm("HTTPS"); //makes identity verification in the ssl context - * - * - * If the socket parameter is an instance of SSLSocket, and the endpoint identification algorithm of the - * SSLParameters is non-empty, to prevent man-in-the-middle attacks, the address that the socket connected to - * should be checked against the peer's identity presented in the end-entity X509 certificate, as specified in - * the endpoint identification algorithm. - * - * - * If the socket parameter is an instance of SSLSocket, and the algorithm constraints of the SSLParameters is - * non-null, for every certificate in the certification path, fields such as subject public key, the signature - * algorithm, key usage, extended key usage, etc. need to conform to the algorithm constraints in place on this - * socket.*/ - - private X509ExtendedTrustManager delegate; - - public CustomX509ExtendedTrustManager(X509ExtendedTrustManager delegate){ - this.delegate = delegate; - } - - @Override - public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException { - delegate.checkClientTrusted(x509Certificates, s, socket); - } - - @Override - public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException { - delegate.checkServerTrusted(x509Certificates, s, socket); - } - - @Override - public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException { - delegate.checkClientTrusted(x509Certificates, s, sslEngine); - } - - @Override - public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException { - delegate.checkServerTrusted(x509Certificates, s, sslEngine); - } - - @Override - public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { - delegate.checkClientTrusted(x509Certificates, s); - } - - @Override - public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { - delegate.checkServerTrusted(x509Certificates, s); - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return delegate.getAcceptedIssuers(); - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index d218c6e56..9863ba390 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -1,5 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; +import java.util.Date; import javax.net.ssl.*; import java.io.IOException; import java.io.InputStream; @@ -33,10 +34,23 @@ public static TrustManager[] getX509ExtTrustManager( final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE - /* filterTrustAnchors for validation + /* + * The following code will filter the certificates from the trustStore by the + * revocation date. Only certificates that consist validity of at least one remaining + * day will be accepted + * + * //toDo not working yet because root certificates do not have CRL and OSCP links for + * revocation checks.. + * + // filterTrustAnchors for validation, at least one day valid + Date validityDate = new Date(); + validityDate.setTime(validityDate.getTime() + 86400000); + + PKIXBuilderParameters pkixParamBuilder = filterTrustAnchors(trustStore, validityDate); ManagerFactoryParameters trustParams = - new CertPathTrustManagerParameters(filterTrustAnchors(trustStore)); + new CertPathTrustManagerParameters(pkixParamBuilder); trustManagerFactory.init(trustParams);*/ + trustManagerFactory.init(trustStore); myTrustManager = trustManagerFactory.getTrustManagers(); @@ -44,7 +58,6 @@ public static TrustManager[] getX509ExtTrustManager( //allow only X509 Authentication if (myTrustManager.length == 1 && myTrustManager[0] instanceof X509ExtendedTrustManager) { //toDo algorithm constraints - //hostname verification is currently done by using https identification protocol return myTrustManager; } else { throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(myTrustManager)); @@ -118,7 +131,7 @@ public static Key getKey( } } - private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore) + private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore, Date validityUntilDate) throws KeyStoreException, InvalidAlgorithmParameterException { PKIXParameters params = new PKIXParameters(keyStore); @@ -130,7 +143,7 @@ private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore) myTrustAnchors.stream().filter( ta -> { try { - ta.getTrustedCert().checkValidity(/* toDo expiration date*/); + ta.getTrustedCert().checkValidity(validityUntilDate); } catch (CertificateException e) { return false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java new file mode 100644 index 000000000..e36fc2d10 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java @@ -0,0 +1,110 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; + +import java.security.cert.Certificate; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A class for verifying an established TLS Session on application layer + * + * @author Leon Beckmann (leon.beckmannn@aisec.fraunhofer.de) + */ +public class TlsSessionVerificationHelper { + private static final Logger LOG = LoggerFactory.getLogger(TlsSessionVerificationHelper.class); + + /* + * Returns true if the ssl session is valid and the remote host can be trusted + * + * Due to the fact, that hostname verification is not specified in the secure socket layer, + * we have to check if the connected hostname matches to the subject of the peer certificate to + * avoid Man-In-The-Middle Attacks. + * + * Further we check the peer certificate validity to avoid the case that some of the certificates + * in our local trust_store are not valid anymore and allow a peer connector to connect with an + * expired certificate + */ + public static boolean verifyTlsSession(SSLSession sslSession) { + + LOG.debug("Connected to {}:{}", sslSession.getPeerHost(), sslSession.getPeerPort()); + try { + Certificate[] certificates = sslSession.getPeerCertificates(); + + if (certificates.length != 1) { + LOG.warn("Unexpected number of certificates"); + return false; + } + X509Certificate peerCert = (X509Certificate) certificates[0]; + + //check hostname verification + Collection> sans = peerCert.getSubjectAlternativeNames(); + if (sans == null) { + LOG.warn("No Subject alternative names for hostname verification provided"); + return false; + } + + ArrayList hostNames = new ArrayList<>(); + + for (List subjectAltName : sans) { + if (subjectAltName.size() != 2) { + continue; + } + Object value = subjectAltName.get(1); + switch ((Integer)subjectAltName.get(0)) { + case 2: //DNS_NAME + case 7: //IP_ADDRESS + if (value instanceof String) { + hostNames.add((String)value); + } else if (value instanceof byte[]) { + hostNames.add(new String((byte[]) value)); + } + break; + case 0: //OTHER_NAME - Not Supported + case 1: //RFC_822_Name - Not Supported + case 3: //X400_ADDRESS - Not Supported + case 4: //DIRECTORY_NAME - Not Supported + case 5: //EDI_PARTY_NAME - Not supported + case 6: //URI - Not Supported + case 8: //REGISTERED_ID - Not Supported + default: //unspecified General Name - should never happen + break; + } + } + + //toDo localhost is matched manually to 127.0.0.1 for testing.. a matching file ip <-> dns + // would be nicer in the future + if (hostNames.contains("localhost")) { + hostNames.add("127.0.0.1"); + } + + if (!hostNames.contains(sslSession.getPeerHost())) { + LOG.warn("Hostname verification failed. Peer certificate does not belong to peer host"); + return false; + } + + //check certificate validity for now and at least one day + Date oneDay = new Date(); + oneDay.setTime(oneDay.getTime() + 86400000); + + peerCert.checkValidity(); + peerCert.checkValidity(oneDay); + + } catch (SSLPeerUnverifiedException | CertificateParsingException | + CertificateNotYetValidException | CertificateExpiredException e) { + LOG.warn("TLS Session Verification failed", e); + return false; + } + + return true; + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 1c9f7400c..4a40f885f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -1,15 +1,10 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.net.SocketTimeoutException; -import java.util.ArrayList; /** * A simple Listener thread that listens to an input stream and notifies all listeners when new data were received @@ -42,8 +37,6 @@ public void run(){ this.listener.onMessage(buf); } catch (SocketTimeoutException ignore) { //timeout to catch safeStop() call - //alternative: close socket / InputStream and catch exception SocketException - } catch (EOFException e){ listener.onClose(); running = false; //terminate @@ -59,7 +52,7 @@ public void register(DataAvailableListener listener) { this.listener = listener; } - + @Override public void safeStop() { this.running = false; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 93c85f7a0..eef139675 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsSessionVerificationHelper; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; @@ -91,9 +92,9 @@ public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) SSLParameters sslParameters = sslSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(false); //use server priority order sslParameters.setNeedClientAuth(true); - sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.2 + sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher - sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification + //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); is done in application layer sslSocket.setSSLParameters(sslParameters); LOG.debug("TLS Client was initialized successfully"); } @@ -200,14 +201,22 @@ public boolean isConnected(){ return clientSocket != null && clientSocket.isConnected(); } - public SSLSession getSslSession() { - return ((SSLSocket)clientSocket).getSession(); - } - @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { //start receiving listener after TLS Handshake was successful - LOG.debug("TLS Handshake was successful. Starting input listener thread"); + if (LOG.isDebugEnabled()) { + LOG.debug("TLS Handshake was successful"); + } + + // verify tls session on application layer: hostname verification, certificate validity + if (!TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession())) { + if (LOG.isWarnEnabled()) { + LOG.warn("TLS session is not valid. Close TLS connection"); + } + disconnect(); + callback.secureChannelConnectHandler(null); + return; + } SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 5b0cebd24..10a07ba8c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -85,9 +85,6 @@ public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, sslParameters.setNeedClientAuth(true); //client must authenticate sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite - //FIXME uncomment hostname identification, this is deactivated because the client uses a certificate of an - // other identity in the examples at the moment - //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //use https for hostname verification sslServerSocket.setSSLParameters(sslParameters); LOG.debug("TLS server was initialized successfully"); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 2aaecad0d..768a0281f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -1,17 +1,16 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsSessionVerificationHelper; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; -import javax.net.ssl.SSLHandshakeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; -import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocket; import java.io.*; import java.net.SocketTimeoutException; @@ -51,6 +50,7 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private IDSCPv2Callback configCallback; //no race conditions private IdscpConnectionListener idscpServerCallback; //no race conditions private CountDownLatch listenerLatch = new CountDownLatch(1); + private CountDownLatch tlsVerificationLatch = new CountDownLatch(1); TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback configCallback, IdscpConnectionListener idscpServerCallback){ @@ -76,8 +76,17 @@ public void run(){ // the thread would wait forever in onError() until handshakeCompleteListener is called try { sslSocket.startHandshake(); + //wait for tls session verification + while (true) { + try { + tlsVerificationLatch.await(); + break; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } } catch (IOException e) { - LOG.warn("SSLHandshakeException occurred. Quit server session"); + LOG.warn("SSLHandshakeException occurred. Quit server session", e); running = false; } @@ -90,11 +99,8 @@ public void run(){ in.readFully(buf, 0, len); onMessage(buf); - } catch (SocketTimeoutException e) { + } catch (SocketTimeoutException ignore) { //timeout catches safeStop() call and allows to send server_goodbye - //alternative: close sslSocket and catch SocketException - //continue - } catch (EOFException e){ onClose(); running = false; @@ -178,7 +184,24 @@ public boolean isConnected() { @Override public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) { - LOG.debug("TLS handshake was successful"); + if (LOG.isDebugEnabled()) { + LOG.debug("TLS Handshake was successful"); + } + + // verify tls session on application layer: hostname verification, certificate validity + if (!TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession())) { + if (LOG.isWarnEnabled()) { + LOG.warn("TLS session is not valid. Close TLS connection"); + } + running = false; //set running false before tlsVerificationLatch is decremented + tlsVerificationLatch.countDown(); + return; + } else { + LOG.debug("TLS session is valid"); + tlsVerificationLatch.countDown(); + } + + SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index e076095cc..aa6dc128f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -62,9 +62,6 @@ enum FSM_STATE { public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout){ - this.secureChannel = secureChannel; - secureChannel.setFsm(this); - /* ------------- Timeout Handler Routines ------------*/ Runnable handshakeTimeoutHandler = () -> { @@ -106,6 +103,9 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, //set initial state currentState = states.get(FSM_STATE.STATE_CLOSED); + + this.secureChannel = secureChannel; + secureChannel.setFsm(this); } private void checkForFsmCircles() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 5b10bbd33..077ecfaac 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -40,7 +40,7 @@ public StateClosed(FSM fsm, if (!fsm.sendFromFSM(idscpHello)) { LOG.error("Cannot send IdscpHello. Close connection"); runEntryCode(fsm); - onMessageLock.notifyAll(); + onMessageLock.signalAll(); return fsm.getState(FSM_STATE.STATE_CLOSED); } From 835abb94395fcc00df076e357a7cdeea86a57334 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Sun, 29 Mar 2020 14:22:32 +0200 Subject: [PATCH 060/237] Add full comments to IDSCP Core and Driver Interfaces --- .../aisec/ids/idscp2/IDSCPv2Initiator.java | 23 +- .../idscp2/drivers/interfaces/DapsDriver.java | 8 + .../drivers/interfaces/RatProverDriver.java | 18 +- .../drivers/interfaces/RatVerifierDriver.java | 18 +- .../interfaces/SecureChannelDriver.java | 23 +- .../drivers/interfaces/SecureServer.java | 14 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 22 +- .../idscp_core/IdscpMessageFactory.java | 6 +- .../idscp2/idscp_core/IdscpMsgListener.java | 13 +- .../configuration/AttestationConfig.java | 3 +- .../configuration/IDSCPv2Callback.java | 28 ++- .../configuration/IDSCPv2Configuration.java | 41 ++-- .../configuration/IDSCPv2Settings.java | 3 +- .../finite_state_machine/Event.java | 23 +- .../idscp_core/finite_state_machine/FSM.java | 228 +++++++++++++++--- .../finite_state_machine/FsmListener.java | 33 ++- .../InternalControlMessage.java | 6 + .../finite_state_machine/State.java | 21 +- .../finite_state_machine/StateClosed.java | 12 +- .../StateEstablished.java | 6 + .../StateWaitForDatAndRat.java | 7 + .../StateWaitForDatAndRatVerifier.java | 8 + .../StateWaitForHello.java | 10 +- .../finite_state_machine/StateWaitForRat.java | 7 + .../StateWaitForRatProver.java | 6 + .../StateWaitForRatVerifier.java | 6 + .../finite_state_machine/Timer.java | 12 + .../finite_state_machine/TimerThread.java | 25 +- .../finite_state_machine/Transition.java | 5 +- .../idscp_server/IDSCPv2Server.java | 30 ++- .../idscp_server/IdscpConnectionListener.java | 12 + .../rat_registry/RatProverDriverRegistry.java | 34 ++- .../RatVerifierDriverRegistry.java | 28 +++ .../secure_channel/SecureChannel.java | 25 +- .../secure_channel/SecureChannelEndpoint.java | 29 ++- .../secure_channel/SecureChannelListener.java | 15 ++ 36 files changed, 654 insertions(+), 154 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java index 23994ca47..7ff21c26d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java @@ -3,20 +3,25 @@ import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; /** - * An interface for the IDSCPv2Initiator class, that implements callback functions that notifies the user about - * new connections, errors and closed connections - * - * Developer API - * - * Methods: - * void onConnect(IDSCPv2Connection) to notify the user a new connection was created - * void errorHandler(String error) to notify the user about an error occurred - * void connectionClosedHandler(String connectionId) to notify the user about connection was closed + * An interface for the IDSCPv2Initiator class, that implements callback functions that notifies + * the user about new connections, errors and closed connections * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface IDSCPv2Initiator { + + /* + * Called when a new connection is established + */ void newConnectionHandler(IDSCPv2Connection connection); + + /* + * Called when an error occurred in the underlying IDSCPv2 protocol + */ void errorHandler(String error); + + /* + * Called when a connection with the given connectionID was closed + */ void connectionClosedHandler(String connectionId); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index 4ae55525d..2fa4351ce 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -6,6 +6,14 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface DapsDriver { + + /* + * Receive a token from the DapsDriver + */ byte[] getToken(); + + /* + * Verify a Daps token + */ long verifyToken(byte[] dat, Object securityRequirements); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index fdcdc2d84..581d81d65 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -1,20 +1,30 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * An abstract RatProverDriver class that creates a rat prover driver thread and proves itself to + * the peer connector using remote attestation + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public abstract class RatProverDriver extends Thread{ private static final Logger LOG = LoggerFactory.getLogger(RatProverDriver.class); protected boolean running = true; protected FsmListener fsmListener; - protected boolean successful = false; - protected final Object resultAvailableLock = new Object(); - public void delegate(IDSCPv2.IdscpMessage message){} + /* + * Delegate an IDSCPv2 message to the RatProver driver + */ + public void delegate(IdscpMessage message){} + /* + * Terminate and cancel the RatProver driver + */ public void terminate() { running = false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 406748aa8..254a97642 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -1,20 +1,30 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * An abstract RatVerifierDriver class that creates a rat verifier driver thread and verifier the + * peer connector using remote attestation + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public abstract class RatVerifierDriver extends Thread{ private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDriver.class); protected boolean running = true; protected FsmListener fsmListener; - protected boolean successful = false; - protected final Object resultAvailableLock = new Object(); - public void delegate(IDSCPv2.IdscpMessage message){} + /* + * Delegate the IDSCPv2 message to the RatVerifier driver + */ + public void delegate(IdscpMessage message){} + /* + * Terminate and cancel the RatVerifier driver + */ public void terminate() { running = false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index a480d075e..2ea75dcd4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -5,24 +5,21 @@ import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; /** - * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function for IDSCPv2 clients and - * a listen() function for IDSCPv2 servers - * - * Developer API - * - * Methods: - * void connect(IDSCPv2Settings, IDSCPv2Callback) to create an IDSCPv2 connection to the host from the settings - * registers a callback for errors and return of a secure channel - * - * SecureServer listen(IDSCPv2Settings, IDSCPv2Callback, IdscpConnectionListener) - * - * to create an IDSCPv2 server configured by the IDSCPv2 settings registers callbacks - * for errors and new incoming connections + * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function + * for IDSCPv2 clients and a listen() function for IDSCPv2 servers to connect the underlying layer * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface SecureChannelDriver { + + /* + * Asynchronous method to create a secure connection to a secure server + */ void connect(IDSCPv2Settings settings, IDSCPv2Callback configCallback); + + /* + * Starting a secure server + */ SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, IdscpConnectionListener idscpServerCallback); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java index 86ab13a90..260439be5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java @@ -3,15 +3,17 @@ /** * An interface for the IDSCPv2 Secure Server * - * Developer API - * - * Methods: - * void safeStop() to terminate the server - * boolean isRunning() to check if the server is running - * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface SecureServer { + + /* + * Terminate the secure server + */ void safeStop(); + + /* + * Check if the secure server is running + */ boolean isRunning(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index 09e419e6e..ad26a3428 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -2,24 +2,14 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; /** - * The IDSCPv2 Connection class - * - * User/Developer API: - * - * Methods: - * void close() to close an IDSCP connection - * void send(IdscpMessage) to send an idscp message to the other idscp endpoint - * void onMessage() to receive an asynchronous message from the other idscp endpoint - * boolean isConnected() to check if the idscp connection is still open + * The IDSCPv2 Connection class holds connections between connectors * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -38,13 +28,20 @@ public IDSCPv2Connection(FSM fsm, String connectionId, IDSCPv2Initiator user, Id this.server = server; } + /* + * Close the idscp connection + */ public void close() { + // unregister connection from the idscp server if (server != null) { server.connectionClosedHandler(connectionId); } fsm.terminate(); } + /* + * Send data to the peer idscp connector + */ public void send(byte[] msg) { LOG.debug("Send idscp message"); fsm.send(IdscpMessageFactory.getIdscpDataMessage(msg)); @@ -64,6 +61,9 @@ public void onClose() { } } + /* + * Check if the idscp connection is currently established + */ public boolean isConnected() { return fsm.isConnected(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index f565a3f7f..ae951d00e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -2,9 +2,13 @@ import com.google.protobuf.ByteString; import de.fhg.aisec.ids.messages.IDSCPv2.*; - import java.util.Arrays; +/** + * A factory for creating IDSCPv2 messages + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class IdscpMessageFactory { public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java index 1171fdec1..37ed40008 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java @@ -1,8 +1,17 @@ package de.fhg.aisec.ids.idscp2.idscp_core; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; - +/** + * An interface for an IDSCP message listener + */ public interface IdscpMsgListener { + + /* + * notify the listener about new data via idscp + */ void onMessage(byte[] data); + + /* + * notify the listener that the idscp connection was closed + */ void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index 9c7a30457..fbb1214c8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -1,7 +1,8 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; /** - * Attestation configuration class, containing attestation suite for supported / expected attestation types + * Attestation configuration class, containing attestation suite for supported / expected + * attestation types * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java index 230f571c0..91bc2923b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java @@ -4,20 +4,24 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; /** - * An callback interface, that implements callback functions that notifies about new secureChannels, errors and closed - * connections - * - * Developer API - * - * Methods: - * void secureChannelConnectHandler(SecureChannel) to notify the client about a new secure channel - * void secureChannelListenHandler(SecureChannel, IdscpConnectionListener) to notify the server about new secureChannel - * void connectionClosedHandler(String connectionId) to notify listener about connection was closed + * An callback interface that implements callback functions that notifies about new + * secureChannels * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface IDSCPv2Callback { + + /* + * Notify the client about a new secure channel + */ void secureChannelConnectHandler(SecureChannel secureChannel); - void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer); - void connectionClosedHandler(String connectionId); -} + + /* + * Notify the server about new secureChannel + */ + void secureChannelListenHandler( + SecureChannel secureChannel, + IdscpConnectionListener idscpServer + ); + +} \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index 8b04db0df..d9b06300f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -10,19 +10,11 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.util.UUID; /** * IDSCPv2Configuration class, provides IDSCPv2 API to the User (IDSCPv2Initiator) * - * User API - * - * Methods: - * void connect(IDSCPv2Settings) initiate idscpv2 connect to host from settings - * SecureServer listen(IDSCPv2Settings) initiate creation of a - * void secureChannelConnectHandler(SecureChannel) - * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class IDSCPv2Configuration implements IDSCPv2Callback { @@ -51,11 +43,18 @@ public IDSCPv2Configuration(IDSCPv2Initiator initiator, this.ratTimeout = ratTimeout; } + /* + * User API to create a IDSCPv2 connection as a client + */ public void connect(IDSCPv2Settings settings){ LOG.info("Connect to an idscpv2 server ({})", settings.getHost()); secureChannelDriver.connect(settings, this); } + /* + * User API to create a new IDSCPv2 Server that starts a Secure Server that listens to new + * secure channels + */ public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { LOG.info("Starting new IDSCPv2 server at port {}", settings.getServerPort()); @@ -70,6 +69,16 @@ public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { return idscpServer; } + /* + * A callback implementation to receive a new established secure channel from an Secure client + * + * If the secure channel is null, no secure channel was established and an error is provided + * to the user + * + * If the secure channel was established, a new FSM is created for this connection and the + * IDSCPv2 handshake is started. After a successful handshake, a new IDSCPv2Connection is + * created and provided to the user + */ @Override public void secureChannelConnectHandler(SecureChannel secureChannel) { if (secureChannel == null){ @@ -94,6 +103,16 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { } } + /* + * A callback implementation to receive a new established secure channel from an Secure server + * + * If the secure channel is null, no secure channel was established and the result will be + * ignored + * + * If the secure channel was established, a new FSM is created for this connection and the + * IDSCPv2 handshake is started. After a successful handshake, a new IDSCPv2Connection is + * created and provided to the user and the IDSCPv2 server + */ @Override public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { if (secureChannel != null){ @@ -118,10 +137,4 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnect LOG.warn("An incoming idscpv2 client connection request failed because no secure channel was established"); } } - - @Override - public void connectionClosedHandler(String connectionId) { - LOG.info("IDSCPv2 connection with id {} has been closed", connectionId); - user.connectionClosedHandler(connectionId); - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java index 554764686..963d19251 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java @@ -4,7 +4,8 @@ import org.checkerframework.checker.units.qual.A; /** - * IDSCPv2 configuration class, containing information about keyStore and TrustStores, Attestation Types, host, ... + * IDSCPv2 configuration class, contains information about keyStore and TrustStores, + * Attestation Types, host, DAPS, ... * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index f4c42d814..e8a2559e6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -5,10 +5,10 @@ import javax.swing.*; /** - * An Event class for the Finite State Machine. Triggers a transition and holds either an idscpMessage or an - * InternalControlMessage. + * An Event class for the Finite State Machine. Triggers a transition and holds + * either an IdscpMessage or an InternalControlMessage, or both in special cases. * - * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class Event { public enum EventType { @@ -21,6 +21,9 @@ public enum EventType { private IdscpMessage idscpMessage; private InternalControlMessage controlMessage; + /* + * Create an Event with an Internal Control Message + */ public Event(InternalControlMessage controlMessage){ this.key = controlMessage.getValue(); this.type = EventType.INTERNAL_CONTROL_MESSAGE; @@ -28,6 +31,9 @@ public Event(InternalControlMessage controlMessage){ this.idscpMessage = null; } + /* + * Create an Event with an Idscpv2 Message + */ public Event (IdscpMessage idscpMessage){ this.key = idscpMessage.getMessageCase().getNumber(); this.type = EventType.IDSCP_MESSAGE; @@ -35,7 +41,11 @@ public Event (IdscpMessage idscpMessage){ this.controlMessage = null; } - //for outgoing ratProver and ratVerifier messages + /* + * Create a event for outgoing RatProver and RatVerifier messages + * + * throws an IllegalStateException if this event is requested for other purposes + */ public Event (InternalControlMessage controlMessage, IdscpMessage idscpMessage){ if (controlMessage.equals(InternalControlMessage.RAT_PROVER_MSG) || controlMessage.equals(InternalControlMessage.RAT_VERIFIER_MSG)) @@ -45,11 +55,14 @@ public Event (InternalControlMessage controlMessage, IdscpMessage idscpMessage){ this.idscpMessage = idscpMessage; this.controlMessage = controlMessage; } else { - throw new IllegalStateException("This constructor must only be by RAT_PROVER and " + + throw new IllegalStateException("This constructor must only be used by RAT_PROVER and " + "RAT_VERIFIER for message passing"); } } + // + // Getter methods + // public Object getKey() { return key; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index aa6dc128f..9ce383215 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -3,12 +3,10 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCPv2; import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,6 +16,16 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; +/** + * The finite state machine FSM of the IDSCPv2 protocol + * + * Manages IDSCPv2 Handshake, Re-Attestation, DAT-ReRequest and DAT-Re-Validation. Delivers + * Internal Control Messages and Idscpv2Messages to the target receivers, + * creates and manages the states and its transitions and implements security restriction to protect + * the protocol against misuse and faulty, insecure or evil driver implementations. + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); @@ -38,26 +46,62 @@ enum FSM_STATE { private State currentState; /* ---------------- end of states --------------- */ - private SecureChannel secureChannel; + private SecureChannel secureChannel; //secure underlying channel private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; - private String currentRatProverId; //avoid messages from old provers - private String currentRatVerifierId; //avoid messages from old verifiers - private String proverMechanism = null; - private String verifierMechanism = null; + /* + * RAT Driver Thread ID to identify the driver threads and check if messages are provided by + * the current active driver or by any old driver, whose lifetime is already over + * + * Only one driver can be valid at a time + */ + private String currentRatProverId; //avoid messages from old prover drivers + private String currentRatVerifierId; //avoid messages from old verifier drivers + + /* + * RAT Mechanisms, calculated during handshake in WAIT_FOR_HELLO_STATE + */ + private String proverMechanism = null; //RAT prover mechanism + private String verifierMechanism = null; //RAT Verifier mechanism + + /* + * The idscp message listener, that should receive the IDSCPv2 messages from the fsm + * And a listener latch to ensure that the listener is available and the message does not get + * lost + */ private IdscpMsgListener listener = null; private final CountDownLatch listenerLatch = new CountDownLatch(1); - private final ReentrantLock fsmIsBusy = new ReentrantLock(true); //use a fair synchronization lock (FIFO) + + /* + * A FIFO-fair synchronization lock for the finite state machine + */ + private final ReentrantLock fsmIsBusy = new ReentrantLock(true); + + /* + * A condition to ensure no idscp messages can be provided by the secure channel to the fsm + * before the handshake was started + */ private final Condition onMessageBlock = fsmIsBusy.newCondition(); + + /* + * A condition for the dscpv2 handshake to wait until the handshake was successful and the + * connection is established or the handshake failed and the fsm is locked forever + */ private final Condition idscpHandshakeLock = fsmIsBusy.newCondition(); private boolean handshakeResultAvailable = false; + + /* + * Check if FSM is closed forever + */ private boolean fsmIsClosed = false; + /* ---------------------- Timer ---------------------- */ private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; + /* ---------------- end of Timer --------------- */ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout){ @@ -84,6 +128,7 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); /* ------------- end timeout routines ------------- */ + /* ------------- FSM STATE Initialization -------------*/ states.put(FSM_STATE.STATE_CLOSED, new StateClosed(this, dapsDriver, onMessageBlock, localSupportedRatSuite, localExpectedRatSuite)); states.put(FSM_STATE.STATE_WAIT_FOR_HELLO, new StateWaitForHello(this, @@ -104,6 +149,7 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, //set initial state currentState = states.get(FSM_STATE.STATE_CLOSED); + //register fsm to the secure channel for bi-directional communication between fsm and sc this.secureChannel = secureChannel; secureChannel.setFsm(this); } @@ -120,7 +166,7 @@ private void checkForFsmCircles() { // // Example: // Thread A stuck within a transition t1 that calls a function that calls - // onControlMessage(InternalError). Then the error is handled in the current state + // onControlMessage(InternalError). Then the error is handled in the current // state and the fsm will switch into state STATE_CLOSED and close all resources. // // Afterwards, the thread will continue the old transition t1 that might use some of the @@ -134,13 +180,20 @@ private void checkForFsmCircles() { } } + /* + * Get a new IDSCPv2 Message from the secure channel and provide it as an event to the fsm + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + */ @Override public void onMessage(byte[] data){ //check for incorrect usage checkForFsmCircles(); - //parse message and create new IDSCP Message Event, then pass it to current state and update new state + //parse message and create new IDSCP Message event, then pass it to current state and + // update new state IdscpMessage message; try { message = IdscpMessage.parseFrom(data); @@ -150,7 +203,8 @@ public void onMessage(byte[] data){ } Event event = new Event(message); - //must wait when fsm is in state STATE_CLOSED --> wait() will be notified when fsm is leaving STATE_CLOSED + //must wait when fsm is in state STATE_CLOSED --> wait() will be notified when fsm is + // leaving STATE_CLOSED fsmIsBusy.lock(); try { while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))){ @@ -169,9 +223,11 @@ public void onMessage(byte[] data){ } finally { fsmIsBusy.unlock(); } - } + /* + * An internal control message (ICM) occurred, provide it to the fsm as an event + */ private void onControlMessage(InternalControlMessage controlMessage) { //create Internal Control Message Event and pass it to current state and update new state Event e = new Event(controlMessage); @@ -184,6 +240,17 @@ private void onControlMessage(InternalControlMessage controlMessage) { } } + /* + * API for RatProver to provide Prover Messages to the fsm + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + * + * Afterwards the event for the fsm is created and the fsm lock is requested + * + * When the RatProverThread does not match the active prover tread id, the event will be + * ignored, else the event is provided to the fsm + */ @Override public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { @@ -210,6 +277,17 @@ public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessa } } + /* + * API for RatVerifier to provide Verifier Messages to the fsm + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + * + * Afterwards the event for the fsm is created and the fsm lock is requested + * + * When the RatVerifierDriver does not match the active verifier tread id, the event will be + * ignored, else the event is provided to the fsm + */ @Override public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { @@ -236,6 +314,9 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMes } } + /* + * Feed the event to the current state and execute the runEntry method if the state has changed + */ private void feedEvent(Event event){ State prevState = currentState; currentState = currentState.feedEvent(event); @@ -245,6 +326,12 @@ private void feedEvent(Event event){ } } + /* + * API to terminate the idscp connection by the user + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + */ public void terminate(){ //check for incorrect usage @@ -256,6 +343,12 @@ public void terminate(){ secureChannel.close(); } + /* + * API for the user to start the IDSCPv2 handshake + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + */ public void startIdscpHandshake() throws IDSCPv2Exception { //check for incorrect usage @@ -291,11 +384,20 @@ public void startIdscpHandshake() throws IDSCPv2Exception { } } + /* + * Send idscp data from the fsm via the secure channel to the peer + */ boolean sendFromFSM(IdscpMessage msg){ //send messages from fsm return secureChannel.send(msg.toByteArray()); } + /* + * Provide an Internal Control Message to the FSM + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + */ @Override public void onError(){ @@ -305,6 +407,12 @@ public void onError(){ onControlMessage(InternalControlMessage.ERROR); } + /* + * Provide an Internal Control Message to the FSM, caused by a secure channel closure + * + * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect + * driver implementations + */ @Override public void onClose(){ @@ -314,6 +422,9 @@ public void onClose(){ onControlMessage(InternalControlMessage.ERROR); } + /* + * Send idscp message from the User via the secure channel + */ public void send(IdscpMessage msg){ //send messages from user only when idscp connection is established fsmIsBusy.lock(); @@ -331,15 +442,24 @@ public void send(IdscpMessage msg){ } } + /* + * Check if FSM is in STATE ESTABLISHED + */ public boolean isConnected(){ return currentState.equals(states.get(FSM_STATE.STATE_ESTABLISHED)); } + /* + * Register an IDSCPv2 message listener + */ public void registerMessageListener(IdscpMsgListener listener){ this.listener = listener; listenerLatch.countDown(); } + /* + * Notify handshake lock about result + */ void notifyHandshakeCompleteLock(){ fsmIsBusy.lock(); try { @@ -350,18 +470,32 @@ void notifyHandshakeCompleteLock(){ } } - //calculate Prover mechanism (strongest remote expected), returns null if no match was found + /* + * Calculate the RatProver mechanism + * + * Return the String of the cipher or null if no match was found + */ String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ //toDo implement logic return localSupportedProver[0]; } - //calculate Verifier mechanism (strongest local expected), returns null if no match was found + /* + * Calculate the RatVerifier mechanism + * + * Return the String of the cipher or null if no match was found + */ String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ //toDo implement logic return localExpectedVerifier[0]; } + /* + * Stop current RatVerifier if active and start the RatVerifier from the + * RatVerifierDriver Registry that matches the verifier mechanism + * + * return false if no match was found + */ boolean restartRatVerifierDriver(){ //assume verifier mechanism is set stopRatVerifierDriver(); @@ -371,11 +505,15 @@ boolean restartRatVerifierDriver(){ currentRatVerifierId = ""; return false; } else { + //safe the thread ID currentRatVerifierId = Long.toString(ratVerifierDriver.getId()); return true; } } + /* + * Terminate the RatVerifierDriver + */ void stopRatVerifierDriver(){ if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ ratVerifierDriver.interrupt(); @@ -383,7 +521,12 @@ void stopRatVerifierDriver(){ } } - + /* + * Stop current RatProver if active and start the RatProver from the + * RatProverDriver Registry that matches the prover mechanism + * + * return false if no match was found + */ boolean restartRatProverDriver(){ //assume prover mechanism is set stopRatProverDriver(); @@ -393,11 +536,15 @@ boolean restartRatProverDriver(){ currentRatProverId = ""; return false; } else { + //safe the thread ID currentRatProverId = Long.toString(ratProverDriver.getId()); return true; } } + /* + * Terminate the RatProverDriver + */ void stopRatProverDriver(){ if (ratProverDriver != null && ratProverDriver.isAlive()){ ratProverDriver.interrupt(); @@ -405,17 +552,10 @@ void stopRatProverDriver(){ } } - void setRatMechanisms(String proverMechanism, String verifierMechanism) { - this.proverMechanism = proverMechanism; - this.verifierMechanism = verifierMechanism; - } - - - - State getState(FSM_STATE state){ - return states.get(state); - } - + /* + * Lock the fsm forever, terminate the timers and drivers, close the secure channel + * and notify User or handshake lock about closure + */ void lockFsm(){ try { secureChannel.close(); @@ -443,14 +583,9 @@ void lockFsm(){ } } - RatVerifierDriver getRatVerifierDriver() { - return ratVerifierDriver; - } - - RatProverDriver getRatProverDriver() { - return ratProverDriver; - } - + /* + * Provide IDSCPv2 message to the message listener + */ void notifyIdscpMsgListener(byte[] data) { try { this.listenerLatch.await(); @@ -460,4 +595,29 @@ void notifyIdscpMsgListener(byte[] data) { Thread.currentThread().interrupt(); } } + + // + // Getter + // + + RatVerifierDriver getRatVerifierDriver() { + return ratVerifierDriver; + } + + RatProverDriver getRatProverDriver() { + return ratProverDriver; + } + + State getState(FSM_STATE state){ + return states.get(state); + } + + // + // Setter + // + + void setRatMechanisms(String proverMechanism, String verifierMechanism) { + this.proverMechanism = proverMechanism; + this.verifierMechanism = verifierMechanism; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index dc651ed0a..a72c40f5d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -1,11 +1,38 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCPv2.*; +/** + * An FSM Listener Interface implemented by the FSM to restrict FSM API to the drivers and the + * secure channel class of the IDSCPv2 + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public interface FsmListener { + + /* + * A method for providing IDSCPv2 data from the secure channel to the FSM + */ void onMessage(byte[] data); - void onRatProverMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); - void onRatVerifierMessage(InternalControlMessage controlMessage, IDSCPv2.IdscpMessage idscpMessage); + + /* + * A method for providing RatProver messages from the RatProverDriver implementation to the FSM + */ + void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage); + + /* + * A method for providing RatVerifier messages from the RatVerifierDriver implementation to the + * FSM + */ + void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage); + + /* + * A method for providing internal errors to the fsm + */ void onError(); + + /* + * A method for notifying the fsm about closure of the secure channel + */ void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index bf6ce52ae..fc62ecdf2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -1,5 +1,11 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; +/** + * An enum that wraps the internal control messages of the IDSCPv2 protocol to trigger transitions + * by non-idscpv2-message-events + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public enum InternalControlMessage { START_IDSCP_HANDSHAKE("ICM_START"), IDSCP_STOP("ICM_STOP"), diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index f3e534315..79f5b1e26 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -4,8 +4,9 @@ import java.util.function.Function; /** - * A State class for the Finite State Machine. A state holds all outgoing transitions and a noTransitionHandler for - * events, that do not trigger any outgoing available transition. Transitions are mapped with the event key + * A State class for the Finite State Machine. + * A state holds all outgoing transitions and a noTransitionHandler for events, that do not trigger + * any outgoing available transition. Transitions are mapped with the event key. * * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de */ @@ -14,6 +15,13 @@ public class State { private ConcurrentHashMap transitions = new ConcurrentHashMap<>(); private Function noTransitionHandler = null; + /* + * A method for triggering aa transition of the current state by a given event + * + * If no transition exists for the given event, the noTransitionHandler is triggered + * + * Returns the target state of the triggered transition (new current state of the fsm) + */ State feedEvent(Event e){ Transition t = transitions.get(e.getKey()); if (t != null){ @@ -23,14 +31,23 @@ State feedEvent(Event e){ } } + /* + * Add ann outgoing transition to the state + */ void addTransition(Object k, Transition t){ transitions.put(k,t); } + /* + * Set the 'no transition available for this event' handler + */ void setNoTransitionHandler(Function noTransitionHandler) { this.noTransitionHandler = noTransitionHandler; } + /* + * run a sequence of code when the state is entered + */ void runEntryCode(FSM fsm) {} } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 077ecfaac..5c305c9e6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -10,7 +10,17 @@ import java.util.concurrent.locks.Condition; - +/** + * The Closed State of the FSM of the IDSCPv2 protocol. + * The FSM is in the Closed state either before any transition was triggered (in this case, the + * Closed State is the FSM Start state) or after the connection was closed (in this case, the + * Closed State is the FSM final state without any outgoing transitions) + * + * When the FSM go from any State into the Closed State again, the FSM is locked forever and all + * involved actors like RatDrivers and Timers will be terminated + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ class StateClosed extends State { private static final Logger LOG = LoggerFactory.getLogger(StateClosed.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index 4db494542..004bf3d8a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -7,6 +7,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Established State of the FSM of the IDSCPv2 protocol. + * Allows message exchange over the IDSCPv2 protocol between two connectors + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateEstablished extends State { private static final Logger LOG = LoggerFactory.getLogger(StateEstablished.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 139342778..59835fde9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -7,6 +7,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Dat_And_Rat State of the FSM of the IDSCPv2 protocol. + * Waits for a new valid dynamic attribute token from the peer as well as for the RatProver and + * RatVerifier to decide whether the connection will be established or not + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForDatAndRat extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRat.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index fae2289f9..f54e3d128 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -7,6 +7,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Dat_And_Rat_Verifier State of the FSM of the IDSCPv2 protocol. + * Wait for a new dynamic attribute token from the peer, since the old one is not valid anymore + * and waits for the RatVerifier after successful verification of the Dat to decide if the idscpv2 + * connection will be established + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForDatAndRatVerifier extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRatVerifier.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index 7f583002b..7f9915325 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -1,6 +1,5 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; - import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; @@ -8,6 +7,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Hello State of the FSM of the IDSCPv2 protocol. + * Waits for the Idscpv2 Hellp Message that contains the protocol version, the supported and + * expected remote attestation cipher suites and the dynamic attribute token (DAT) of the peer. + * + * Goes into the WAIT_FOR_RAT State when valid Rat mechanisms were found and the DAT is valid + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForHello extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForHello.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index 82a599fe2..8f82ca7d3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -7,6 +7,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Rat State of the FSM of the IDSCPv2 protocol. + * Waits for the RatProver and RatVerifier Result to decide whether the connection will be + * established + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForRat extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRat.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index 0b7470f2c..6bb5b2a68 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -7,6 +7,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Rat_Prover State of the FSM of the IDSCPv2 protocol. + * Waits only for the RatProver Result to decide whether the connection will be established + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForRatProver extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRatProver.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index e021d67e4..9a36e65ae 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -7,6 +7,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The Wait_For_Rat_Verifier State of the FSM of the IDSCPv2 protocol. + * Waits only for the RatVerifier Result to decide whether the connection will be established + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class StateWaitForRatVerifier extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRatVerifier.class); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index 7ddfd07c0..b2b2643ab 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -2,6 +2,12 @@ import java.util.concurrent.locks.ReentrantLock; +/** + * A Timer class that provides an API to the FSN to start and cancel timeout threads + * The timer ensures that no canceled timer is able to trigger a timeout transitions + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class Timer { private TimerThread thread = null; @@ -19,6 +25,9 @@ void resetTimeout(long delay){ start(delay); } + /* + * Start a timer thread that triggers the timeout handler routine after a given timout delay + */ public void start(long delay){ mutex.lock(); thread = new TimerThread(delay, timeoutHandler, fsmIsBusy); @@ -26,6 +35,9 @@ public void start(long delay){ mutex.unlock(); } + /* + * Cancel the current timer thread + */ void cancelTimeout(){ mutex.lock(); if (thread != null){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index 1f6041336..253f75cf5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -2,12 +2,19 @@ import java.util.concurrent.locks.ReentrantLock; +/** + * A Timer Thread that triggers timeouts in the fsm + * The thread will only trigger the fsm if it has the fsm lock and the timeout + * was not canceled before + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class TimerThread extends Thread{ private volatile boolean canceled = false; - private long delay; - private final Runnable timeoutHandler; - private final ReentrantLock fsmIsBusy; + private long delay; //timeout delay in seconds + private final Runnable timeoutHandler; //timeout handler routine + private final ReentrantLock fsmIsBusy; //lock for the fsm TimerThread(long delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy){ this.delay = delay; @@ -15,6 +22,15 @@ public class TimerThread extends Thread{ this.fsmIsBusy = fsmIsBusy; } + /* + * Run the timer thread that sleeps the number of timeout delay in ms + * if the timeout was not canceled during the sleep, the thread will request + * the fsm lock and will then check once again, if the timeout was canceled + * by another transition during this process to avoid triggering timeout + * transitions for canceled timers. + * If the timout was not canceled so far, the timer thread calls a timeout handler + * routine, that triggers the timeout transition in the fsm + */ public void run(){ try { Thread.sleep(delay * 1000); @@ -38,6 +54,9 @@ public void run(){ } } + /* + * A method to stop the execution of the timer thread and cancel the timeout + */ public void safeStop(){ canceled = true; this.interrupt(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java index 76ec12731..3a38ed6d2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java @@ -3,9 +3,10 @@ import java.util.function.Function; /** - * Transition class for State machine, provides a doTransition method, that returns the next state for a given event + * Transition class for State machine, provides a doTransition method + * that returns the next state for a given event * - * @author Leon Beckmann leon.beckmann@aisec.fraunhofer.de + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ class Transition { private Function eventHandler; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java index 600998a95..d807b90b6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java @@ -10,6 +10,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; +/** + * An IDSCPv2 Server that has the control about the underlying secure server and caches all active + * connections that belong to the secure server + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class IDSCPv2Server implements IdscpConnectionListener{ private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); @@ -17,15 +23,16 @@ public class IDSCPv2Server implements IdscpConnectionListener{ private CountDownLatch secureServerLatch = new CountDownLatch(1); private ConcurrentHashMap connections = new ConcurrentHashMap<>(); - public IDSCPv2Server(){ - - } + public IDSCPv2Server(){} public IDSCPv2Server(SecureServer secureServer){ this.secureServer = secureServer; secureServerLatch.countDown(); } + /* + * Terminate the IDSCPv2 server, the secure server and close all connections + */ public void terminate(){ LOG.info("Terminating idscp server {}", this.toString()); try { @@ -37,6 +44,9 @@ public void terminate(){ } } + /* + * Close all open IDSCPv2 connections of this server + */ public void terminateAllSessions(){ for (IDSCPv2Connection c : connections.values()){ c.close(); @@ -45,6 +55,9 @@ public void terminateAllSessions(){ } } + /* + * Check if the server is running + */ public boolean isRunning(){ try { secureServerLatch.await(); @@ -55,10 +68,18 @@ public boolean isRunning(){ return false; } + /* + * Get a IDSCPv2Connection from the server cache by the connectionID + * + * return null if no connection was found with this ID + */ public IDSCPv2Connection getConnectionById(String connectionId){ return connections.get(connectionId); } + /* + * return a list of all open IDSCPv2 connections of this server + */ public List getAllConnections(){ return new ArrayList<>(connections.values()); } @@ -75,6 +96,9 @@ public void connectionClosedHandler(String connectionId) { connections.remove(connectionId); } + /* + * Set the corresponding secure server + */ public void setSecureServer(SecureServer secureServer) { this.secureServer = secureServer; secureServerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java index 2857b7ebd..13911c906 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java @@ -2,7 +2,19 @@ import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +/** + * An IDSCP Connection Listener interface that is implemented by the IDSCPv2 Server to notify the + * server about lifetimes of IDSCP connections. The server caches all active connections. + */ public interface IdscpConnectionListener { + + /* + * Notify the server that a new connection was established + */ void newConnectionHandler(IDSCPv2Connection connection); + + /* + * Notify the server that connection has been closed + */ void connectionClosedHandler(String connectionId); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java index 703300b06..071d344b2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -3,8 +3,18 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ConcurrentHashMap; +/** + * A Rat Prover Driver Registry + * The User can register Driver implementation instances and its configurations to the registry + * + * The Idscpv2 protocol will select during the idscp handshake a Rat Prover mechanism and will + * check for this RatProver in this registry + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class RatProverDriverRegistry { private static RatProverDriverRegistry instance; private static ConcurrentHashMap drivers = new ConcurrentHashMap<>(); @@ -19,8 +29,20 @@ public static RatProverDriverRegistry getInstance(){ return instance; } + /* + * To start a Rat Prover from the finite state machine + * + * First we check if the registry contains the RatProver instance, then we create a new + * RatProverDriver from the driver wrapper that holds the corresponding RatProverDriver class. + * + * The finite state machine is registered as the communication partner for the RatProver. + * The RatProver will be initialized with a configuration, if present. Then it is started. + */ public static RatProverDriver startRatProverDriver(String instance, FsmListener listener){ DriverWrapper driverWrapper = drivers.get(instance); + if (driverWrapper == null) { + return null; + } try { RatProverDriver driver = driverWrapper.driverClass.getDeclaredConstructor().newInstance(); @@ -31,12 +53,16 @@ public static RatProverDriver startRatProverDriver(String instance, FsmListener driver.start(); return driver; - } catch (Exception e) { + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { return null; } } + /* + * Register Rat Prover driver and an optional configuration in the registry + */ public void registerDriver( String instance, Class driverClass, @@ -45,10 +71,16 @@ public void registerDriver( drivers.put(instance, new DriverWrapper(driverClass, driverConfig)); } + /* + * Unregister the driver from the registry + */ public void unregisterDriver(String instance){ drivers.remove(instance); } + /* + * An inner static wrapper class, that wraps driver config and driver class + */ private static class DriverWrapper { private Class driverClass; private Object driverConfig; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java index 4b32fc5f6..accdb9ca9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java @@ -6,6 +6,15 @@ import java.util.concurrent.ConcurrentHashMap; +/** + * A Rat Verifier Driver Registry + * The User can register Driver implementation instances and its configurations to the registry + * + * The Idscpv2 protocol will select during the idscp handshake a Rat Verifier mechanism and will + * check for this RatVerifier in this registry + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class RatVerifierDriverRegistry { private static RatVerifierDriverRegistry instance; private static ConcurrentHashMap drivers @@ -20,6 +29,16 @@ public static RatVerifierDriverRegistry getInstance(){ return instance; } + /* + * To start a Rat Verifier from the finite state machine + * + * First we check if the registry contains the RatVerifier instance, then we create a new + * RatVerifierDriver from the driver wrapper that holds the corresponding + * RatVerifierDriver class. + * + * The finite state machine is registered as the communication partner for the RatVerifier. + * The RatVerifier will be initialized with a configuration, if present. Then it is started. + */ public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmListener listener){ DriverWrapper driverWrapper = drivers.get(mechanism); @@ -37,6 +56,9 @@ public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmList } } + /* + * Register Rat Verifier driver and an optional configuration in the registry + */ public void registerDriver( String mechanism, Class driverClass, @@ -45,10 +67,16 @@ public void registerDriver( drivers.put(mechanism, new DriverWrapper(driverClass, driverConfig)); } + /* + * Unregister the driver from the registry + */ public void unregisterDriver(String instance){ drivers.remove(instance); } + /* + * An inner static wrapper class, that wraps driver config and driver class + */ private static class DriverWrapper { private Class driverClass; private Object driverConfig; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index e105a5cdf..4649d7fdb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -3,21 +3,11 @@ import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.util.concurrent.CountDownLatch; /** - * A secureChannel which is the secure underlying basis of the IDSCPv2 protocol, that implements a secureChannelListener - * - * Developer API - * - * Methods: - * void close() to close the secureChannel - * void send(IDSCPv2Message) to send an IDSCPv2Message as bytes via the secure channel - * void onMessage(byte[] data) to receive new bytes via the secure channel - * boolean isConnected() to check if the secure channel is still open - * void registerMessageListener(IdscpMsgListener) to register an idscpv2 message listener - * void setEndpointConnectionId(String id) to set the connectionId + * A secureChannel which is the secure underlying basis of the IDSCPv2 protocol, + * that implements a secureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -32,10 +22,18 @@ public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ this.endpoint = secureChannelEndpoint; } + /* + * close the secure channel forever + */ public void close(){ endpoint.close(); } + /* + * Send data via the secure channel endpoint to the peer connector + * + * return true if the data were sent successfully, else false + */ public boolean send(byte[] msg){ LOG.debug("Send message via secure channel"); return endpoint.send(msg); @@ -78,6 +76,9 @@ public boolean isConnected(){ return endpoint.isConnected(); } + /* + * set the corresponding finite state machine + */ public void setFsm(FsmListener fsm) { this.fsm = fsm; fsmLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index a4a2390ab..77afc5e8a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -1,21 +1,32 @@ package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; /** - * An interface for a secureChannelEndpoint that implements functions to delegate idscp functions to the secure channel - * - * Developer API - * - * Methods: - * void close() disconnect - * void onMessage(int len, byte[]) receive new raw data from connected endpoint - * void send(byte[]) send byte array to connected endpoint - * boolean isConnected() check if endpoint is connected + * An interface for a secureChannelEndpoint e.g. TLS Client and TLS Server Thread + * Used to delegate functions and messages between secure channel and its endpoints * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface SecureChannelEndpoint { + + /* + * API to close the secure channel endpoint + */ void close(); + + /* + * API to delegate messages from an input listener to the secure channel endpoint + */ void onMessage(byte[] bytes); + + /* + * Send data from the secure channel endpoint to the peer connector + * + * return true when data was sent, else false + */ boolean send(byte[] bytes); + + /* + * check if the endpoint is connected + */ boolean isConnected(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java index e4a7b85fc..024f397e2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java @@ -1,7 +1,22 @@ package de.fhg.aisec.ids.idscp2.idscp_core.secure_channel; +/** + * An interface for a secure channel listener, implemented by the secure channel + */ public interface SecureChannelListener { + + /* + * Delegate data from secure channel endpoint to the secure channel + */ void onMessage(byte[] data); + + /* + * Delegate an error from an secure channel endpoint to the secure channel + */ void onError(); + + /* + * Notify secure channel that secure channel endpoint has been closed + */ void onClose(); } From b6e14e1d4486a95f022400f5aebef9fbd77190cc Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Sun, 29 Mar 2020 22:08:11 +0200 Subject: [PATCH 061/237] Update hostname verification: add wildcards, add more comments --- .../TlsSessionVerificationHelper.java | 143 +++++++++++++++--- .../client/DataAvailableListener.java | 15 +- .../secure_channel/client/InputListener.java | 10 +- .../client/InputListenerThread.java | 14 +- .../secure_channel/client/TLSClient.java | 8 +- .../server/TLSServerThread.java | 13 +- 6 files changed, 164 insertions(+), 39 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java index e36fc2d10..c99bbbc8b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java @@ -9,6 +9,8 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import org.slf4j.Logger; @@ -16,43 +18,58 @@ /** * A class for verifying an established TLS Session on application layer + * (application level security) * * @author Leon Beckmann (leon.beckmannn@aisec.fraunhofer.de) */ public class TlsSessionVerificationHelper { private static final Logger LOG = LoggerFactory.getLogger(TlsSessionVerificationHelper.class); + private static final String ipv4Pattern = + "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; + private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}"; + /* - * Returns true if the ssl session is valid and the remote host can be trusted + * Checks if the ssl session is valid and the remote host can be trusted * * Due to the fact, that hostname verification is not specified in the secure socket layer, * we have to check if the connected hostname matches to the subject of the peer certificate to - * avoid Man-In-The-Middle Attacks. + * avoid Man-In-The-Middle Attacks. This is required for every raw tls! * * Further we check the peer certificate validity to avoid the case that some of the certificates * in our local trust_store are not valid anymore and allow a peer connector to connect with an * expired certificate + * + * Throws SSlPeerUnverifiedException if peer certificate is not secure for this peer */ - public static boolean verifyTlsSession(SSLSession sslSession) { + public static void verifyTlsSession(SSLSession sslSession) throws SSLPeerUnverifiedException{ + + String host = sslSession.getPeerHost(); - LOG.debug("Connected to {}:{}", sslSession.getPeerHost(), sslSession.getPeerPort()); + LOG.debug("Connected to {}:{}", host, sslSession.getPeerPort()); try { - Certificate[] certificates = sslSession.getPeerCertificates(); + //get certificate + Certificate[] certificates = sslSession.getPeerCertificates(); if (certificates.length != 1) { - LOG.warn("Unexpected number of certificates"); - return false; + throw new SSLPeerUnverifiedException("Unexpected number of certificates"); } X509Certificate peerCert = (X509Certificate) certificates[0]; - //check hostname verification + /* + * According to RFC6125, hostname verification should be done against the certificate's + * subject alternative name's (SANs) dNSName field or the SANs IPAddress. In some legacy + * implementations, the check is done against the certificate's commonName, but this is + * deprecated for quite a while and is therefore not supported anymore in te IDSCPv2 protocol. + */ Collection> sans = peerCert.getSubjectAlternativeNames(); if (sans == null) { - LOG.warn("No Subject alternative names for hostname verification provided"); - return false; + throw new SSLPeerUnverifiedException("No Subject alternative names for hostname " + + "verification provided"); } - ArrayList hostNames = new ArrayList<>(); + ArrayList acceptedDnsNames = new ArrayList<>(); + ArrayList acceptedIpAddresses = new ArrayList<>(); for (List subjectAltName : sans) { if (subjectAltName.size() != 2) { @@ -61,11 +78,17 @@ public static boolean verifyTlsSession(SSLSession sslSession) { Object value = subjectAltName.get(1); switch ((Integer)subjectAltName.get(0)) { case 2: //DNS_NAME + if (value instanceof String) { + acceptedDnsNames.add((String)value); + } else if (value instanceof byte[]) { + acceptedDnsNames.add(new String((byte[]) value)); + } + break; case 7: //IP_ADDRESS if (value instanceof String) { - hostNames.add((String)value); + acceptedIpAddresses.add((String)value); } else if (value instanceof byte[]) { - hostNames.add(new String((byte[]) value)); + acceptedIpAddresses.add(new String((byte[]) value)); } break; case 0: //OTHER_NAME - Not Supported @@ -82,15 +105,37 @@ public static boolean verifyTlsSession(SSLSession sslSession) { //toDo localhost is matched manually to 127.0.0.1 for testing.. a matching file ip <-> dns // would be nicer in the future - if (hostNames.contains("localhost")) { - hostNames.add("127.0.0.1"); + // automatic dns resolving via DNS service is not ann option since we cannot trust the DNS + if (acceptedDnsNames.contains("localhost")) { + acceptedIpAddresses.add("127.0.0.1"); } - if (!hostNames.contains(sslSession.getPeerHost())) { - LOG.warn("Hostname verification failed. Peer certificate does not belong to peer host"); - return false; + + if (isIpAddress(host)) { + //check ip addresses RFC 2818 (Section 3.1) + if (!acceptedIpAddresses.contains(host)) { + throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " + + "not belong to peer host"); + } + } else { + //check hostname + String[] hostLabels = host.split("\\."); + boolean found = false; + + for (String entry : acceptedDnsNames) { + if (checkHostname(entry.split("\\.", -1), hostLabels)) { + found = true; + break; + } + } + + if (!found) { + throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " + + "not belong to peer host"); + } } + //check certificate validity for now and at least one day Date oneDay = new Date(); oneDay.setTime(oneDay.getTime() + 86400000); @@ -98,13 +143,65 @@ public static boolean verifyTlsSession(SSLSession sslSession) { peerCert.checkValidity(); peerCert.checkValidity(oneDay); - } catch (SSLPeerUnverifiedException | CertificateParsingException | - CertificateNotYetValidException | CertificateExpiredException e) { - LOG.warn("TLS Session Verification failed", e); - return false; + } catch (CertificateParsingException | CertificateNotYetValidException | + CertificateExpiredException e) { + throw new SSLPeerUnverifiedException("TLS Session Verification failed "+ e); + } + } + + + /* + * check if host is an IP Address + */ + private static boolean isIpAddress(String host){ + + Matcher ip4 = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE).matcher(host); + if (ip4.matches()) { + return true; + } + + Matcher ip6 = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE).matcher(host); + return ip6.matches(); + } + + /* + * match dNS Name + */ + private static boolean checkHostname(String[] dnsNameLabels, String[] hostNameLabels) { + + /* + * support wildcard matching of DNS names as described in RFC6125 Section 6.4.3 + * + * Rules: + * 1. The client SHOULD NOT attempt to match a presented identifier in which the wildcard + * character comprises a label other than the left-most label + * (e.g., do not match bar.*.example.net). + * + * 2. If the wildcard character is the only character of the left-most label in the + * presented identifier, the client SHOULD NOT compare against anything but the left-most + * label of the reference identifier (e.g., *.example.com would match foo.example.com but + * not bar.foo.example.com or example.com). + * + * 3. The client MAY match a presented identifier in which the wildcard character is not the + * only character of the label (e.g., baz*.example.net and *baz.example.net and + * b*z.example.net would be taken to match baz1.example.net and foobaz.example.net and + * buzz.example.net, respectively). However, the client SHOULD NOT attempt to match a + * presented identifier where the wildcard character is embedded within an A-label or + * U-label of an internationalized domain name. + */ + if (dnsNameLabels.length == hostNameLabels.length) { //include rule 2 + //all labels without the first one must match completely (rule 1) + for (int i = 1; i < dnsNameLabels.length; i++) { + if (!dnsNameLabels[i].equals(hostNameLabels[i])) { + return false; + } + } + + //first label could include wildcard character '*' (rule 1+3) + return hostNameLabels[0].matches(dnsNameLabels[0].replace("*", ".*")); } - return true; + return false; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java index 062bbd1ea..6249c795e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -1,12 +1,25 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; /** - * An interface for DataAvailableListeners, who will be notified when new data were received + * An interface for DataAvailableListeners, that will be notified when new data were received + * at the sslSocket * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface DataAvailableListener { + + /* + * Provide incoming data to listener + */ void onMessage(byte[] data); + + /* + * Notify listener that an error has occurred + */ void onError(); + + /* + * Notify listener that the socket has been closed + */ void onClose(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java index b3826bad2..09c1338e9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListener.java @@ -1,12 +1,20 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; /** - * An interface for an InputListenerThread, that allows DataAvailableListener registration and safe stop + * An interface for an InputListenerThread, that allows DataAvailableListener registration and + * safe stop * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface InputListener { + /* + * Register a listener for providing data to + */ void register(DataAvailableListener listener); + + /* + * Terminate InputListener + */ void safeStop(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 4a40f885f..d4cc82b43 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -7,12 +7,8 @@ import java.net.SocketTimeoutException; /** - * A simple Listener thread that listens to an input stream and notifies all listeners when new data were received - * - * API: - * - run() to start the listener thread - * - register(DataAvailableListener) to register a new DataAvailableListener who will be notified when receiving data - * - safeStop() to stop the listener thread + * A simple Listener thread that listens to an input stream and notifies a listeners + * when new data were received * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -27,13 +23,19 @@ public InputListenerThread(InputStream in){ this.in = new DataInputStream(in); } + /* + * Run the input listener thread that reads from wire and provides data to upper layer + */ public void run(){ byte[] buf; while (running){ try { + //first read the length int len = in.readInt(); buf = new byte[len]; + //then read the data in.readFully(buf, 0, len); + //provide to listener this.listener.onMessage(buf); } catch (SocketTimeoutException ignore) { //timeout to catch safeStop() call diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index eef139675..b1fd57995 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -209,14 +209,18 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) } // verify tls session on application layer: hostname verification, certificate validity - if (!TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession())) { + try { + TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); + LOG.debug("TLS session is valid"); + } catch (SSLPeerUnverifiedException e) { if (LOG.isWarnEnabled()) { - LOG.warn("TLS session is not valid. Close TLS connection"); + LOG.warn("TLS session is not valid. Close TLS connection", e); } disconnect(); callback.secureChannelConnectHandler(null); return; } + SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 768a0281f..f7ddeadef 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -6,6 +6,7 @@ import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; +import javax.net.ssl.SSLPeerUnverifiedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -189,19 +190,19 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) } // verify tls session on application layer: hostname verification, certificate validity - if (!TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession())) { + try { + TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); + LOG.debug("TLS session is valid"); + tlsVerificationLatch.countDown(); + } catch (SSLPeerUnverifiedException e) { if (LOG.isWarnEnabled()) { - LOG.warn("TLS session is not valid. Close TLS connection"); + LOG.warn("TLS session is not valid. Close TLS connection", e); } running = false; //set running false before tlsVerificationLatch is decremented tlsVerificationLatch.countDown(); return; - } else { - LOG.debug("TLS session is valid"); - tlsVerificationLatch.countDown(); } - SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); From 96293ea66beab451ab8a6839c4352a2d759c7d49 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Mon, 30 Mar 2020 13:26:37 +0200 Subject: [PATCH 062/237] Add comments for TLS --- .../daps/DefaultDapsDriver.java | 88 +++++++++++---- .../daps/DefaultDapsDriverConfig.java | 5 + .../daps/SecurityRequirements.java | 6 ++ .../keystores/PreConfiguration.java | 39 +++---- .../rat/TPM2d/TPM2dHelper.java | 6 +- .../rat/TPM2d/TPM2dProver.java | 100 +++++++++++++++--- .../rat/TPM2d/TPM2dSocket.java | 3 + .../rat/TPM2d/TPM2dVerifier.java | 71 +++++++------ .../rat/TPM2d/Tpm2dProverConfig.java | 5 + .../rat/TPM2d/Tpm2dVerifierConfig.java | 5 + .../rat/TPM2d/TpmMessageFactory.java | 5 + .../rat/dummy/RatProverDummy.java | 16 ++- .../rat/dummy/RatVerifierDummy.java | 17 ++- .../secure_channel/NativeTLSDriver.java | 8 ++ .../TlsSessionVerificationHelper.java | 7 +- .../client/InputListenerThread.java | 1 - .../secure_channel/client/TLSClient.java | 34 ++---- .../secure_channel/server/TLSServer.java | 17 +-- .../server/TLSServerThread.java | 22 +--- .../idscp2/drivers/interfaces/DapsDriver.java | 4 + 20 files changed, 301 insertions(+), 158 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index d708ffc6f..62ca603af 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -36,19 +36,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - /** - * Default DAPS Driver for requesting valid dynamicAttributeToken and verifying DAT + * Default DAPS Driver Implementation for requesting valid dynamicAttributeToken and verifying DAT * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class DefaultDapsDriver implements DapsDriver { private static final Logger LOG = LoggerFactory.getLogger(DefaultDapsDriver.class); - private SSLSocketFactory sslSocketFactory; - private X509ExtendedTrustManager trustManager; - private Key privateKey; + private SSLSocketFactory sslSocketFactory; //ssl socket factory can be reused + private X509ExtendedTrustManager trustManager; //trust manager can be reused + private Key privateKey; //private key can be reused private String connectorUUID; private String dapsUrl; private String targetAudience = "IDS_Connector"; @@ -58,7 +56,7 @@ public DefaultDapsDriver(DefaultDapsDriverConfig config) { this.connectorUUID = config.getConnectorUUID(); this.dapsUrl = config.getDapsUrl(); - //create ssl context + //create ssl socket factory for secure privateKey = PreConfiguration.getKey( config.getKeyStorePath(), config.getKeyStorePassword(), @@ -82,12 +80,17 @@ public DefaultDapsDriver(DefaultDapsDriverConfig config) { } } + /* + * Receive the signed and valid dynamic attribute token from the DAPS + * + * return "INVALID_TOKEN" on failure + */ @Override public byte[] getToken() { String invalidToken = "INVALID_TOKEN"; String token; - LOG.info("Retrieving Dynamic Attribute Token..."); + LOG.info("Retrieving Dynamic Attribute Token from Daps ..."); //create signed JWT String jwt = @@ -126,17 +129,23 @@ public byte[] getToken() { try { //get http response from DAPS - LOG.debug("Acquire DAT from {}", dapsUrl); + if (LOG.isDebugEnabled()) { + LOG.debug("Acquire DAT from {}", dapsUrl); + } Response response = client.newCall(request).execute(); //check for valid response if (!response.isSuccessful()) { - LOG.error("Get unsuccessful http response: {}", response.toString()); + if (LOG.isWarnEnabled()) { + LOG.warn("Get unsuccessful http response: {}", response.toString()); + } return invalidToken.getBytes(); } if (response.body() == null) { - LOG.error("Get empty DAPS response"); + if (LOG.isWarnEnabled()) { + LOG.warn("Get empty DAPS response"); + } return invalidToken.getBytes(); } @@ -145,10 +154,14 @@ public byte[] getToken() { token = json.getString("access_token"); LOG.info("Get access_token from DAPS: {}", token); } else if (json.has("error")) { - LOG.error("Get DAPS error response: {}", json.getString("error")); + if (LOG.isWarnEnabled()) { + LOG.warn("Get DAPS error response: {}", json.getString("error")); + } return invalidToken.getBytes(); } else { - LOG.error("Get unknown DAPS response format: {}", json.toString()); + if (LOG.isWarnEnabled()) { + LOG.warn("Get unknown DAPS response format: {}", json.toString()); + } return invalidToken.getBytes(); } @@ -157,7 +170,9 @@ public byte[] getToken() { LOG.info("DAT is valid"); return token.getBytes(); } else { - LOG.error("DAT validation failed"); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT validation failed"); + } return invalidToken.getBytes(); } } catch (IOException e) { @@ -166,6 +181,15 @@ public byte[] getToken() { } } + /* + * Verify a given dynamic attribute token + * + * If the security requirements is not null and an instance of the SecurityRequirements class + * the method will also check the provided security attributes of the connector that belongs + * to the provided DAT + * + * Return the number of seconds, des DAT is valid, or -1 if validation failed + */ @Override public long verifyToken(byte[] dat, Object securityRequirements) { @@ -202,23 +226,31 @@ public long verifyToken(byte[] dat, Object securityRequirements) { JwtClaims claims; NumericDate expTime; - LOG.debug("Request JWKS from DAPS for validating DAT"); + if (LOG.isDebugEnabled()) { + LOG.debug("Request JWKS from DAPS for validating DAT"); + } try { claims = jwtConsumer.processToClaims(new String(dat)); expTime = claims.getExpirationTime(); } catch (InvalidJwtException e) { - LOG.error("DAPS response is not a valid DAT format", e); + if (LOG.isWarnEnabled()) { + LOG.warn("DAPS response is not a valid DAT format", e); + } return -1; } catch (MalformedClaimException e) { - LOG.error("DAT does not contain expiration time", e); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not contain expiration time", e); + } return -1; } long validityTime = expTime.getValue() - NumericDate.now().getValue(); //check security requirements if (securityRequirements != null) { - LOG.debug("Validate security attributes"); + if (LOG.isDebugEnabled()) { + LOG.debug("Validate security attributes"); + } if (securityRequirements instanceof SecurityRequirements) { SecurityRequirements secRequirements = (SecurityRequirements) securityRequirements; @@ -235,12 +267,16 @@ public long verifyToken(byte[] dat, Object securityRequirements) { LOG.info("DAT is valid and secure"); return validityTime; } else { - LOG.warn("DAT does not fulfill the security requirements"); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements"); + } return -1; } } else { //invalid security requirements format - LOG.error("Invalid security requirements format. Expected SecurityRequirements.class"); + if (LOG.isWarnEnabled()) { + LOG.warn("Invalid security requirements format. Expected SecurityRequirements.class"); + } return -1; } } else { @@ -253,20 +289,26 @@ private SecurityRequirements parseSecurityRequirements(String dynamicAttrToken) JSONObject asJson = new JSONObject(dynamicAttrToken); if (!asJson.has("ids_attributes")) { - LOG.error("DAT does not contain ids_attributes"); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not contain ids_attributes"); + } return null; } JSONObject idsAttributes = asJson.getJSONObject("ids_attributes"); if (!idsAttributes.has("security_profile")) { - LOG.error("DAT does not contain security_profile"); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not contain security_profile"); + } return null; } JSONObject securityProfile = idsAttributes.getJSONObject("security_profile"); //check if all security requirements are available if (!securityProfile.has("audit_logging")) { - LOG.error("DAT does not contain audit_logging"); + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not contain audit_logging"); + } return null; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java index 2979228a2..63e28c2b5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java @@ -2,6 +2,11 @@ import org.checkerframework.checker.nullness.qual.NonNull; +/** + * A Configuration class for the DefaultDapsDriver + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class DefaultDapsDriverConfig { @NonNull private String dapsUrl = "https://daps.aisec.fraunhofer.de"; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java index 097bc2cb7..5d62a7b2f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -3,6 +3,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; +/** + * A Security-Requirements class using Builder pattern to store the connectors expected + * security attributes e.g. Audit Logging + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class SecurityRequirements { private int auditLogging; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index 9863ba390..e02a0745a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -18,8 +18,13 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class PreConfiguration { - //private static final Logger LOG = LoggerFactory.getLogger(TLSPreConfiguration.class); + /* + * Get a secure X509ExtendedTrustManager for the SslContext + * + * throws IllegalStateException if number of available X509TrustManager is not one + * throws RuntimeException of creating TrustManager fails + */ public static TrustManager[] getX509ExtTrustManager( String trustStorePath, String trustStorePassword @@ -34,23 +39,6 @@ public static TrustManager[] getX509ExtTrustManager( final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE - /* - * The following code will filter the certificates from the trustStore by the - * revocation date. Only certificates that consist validity of at least one remaining - * day will be accepted - * - * //toDo not working yet because root certificates do not have CRL and OSCP links for - * revocation checks.. - * - // filterTrustAnchors for validation, at least one day valid - Date validityDate = new Date(); - validityDate.setTime(validityDate.getTime() + 86400000); - - PKIXBuilderParameters pkixParamBuilder = filterTrustAnchors(trustStore, validityDate); - ManagerFactoryParameters trustParams = - new CertPathTrustManagerParameters(pkixParamBuilder); - trustManagerFactory.init(trustParams);*/ - trustManagerFactory.init(trustStore); myTrustManager = trustManagerFactory.getTrustManagers(); @@ -67,6 +55,12 @@ public static TrustManager[] getX509ExtTrustManager( } } + /* + * Get a secure X509ExtendedKeyManager for the SslContext + * + * throws IllegalStateException if number of available X509KeyManager is not one + * throws RuntimeException of creating KeyManager fails + */ public static KeyManager[] getX509ExtKeyManager( String keyStorePath, String keyStorePassword, @@ -103,6 +97,11 @@ public static KeyManager[] getX509ExtKeyManager( } } + /* + * Get a private key from a JKS Keystore + * + * throws RuntimeException if key is not available or key access was not permitted + */ public static Key getKey( String keyStorePath, String keyStorePassword, @@ -131,6 +130,10 @@ public static Key getKey( } } + /* + * This method can be used for filtering certificates in the trust store + * to avoid expired certificates + */ private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore, Date validityUntilDate) throws KeyStoreException, InvalidAlgorithmParameterException { PKIXParameters params = new PKIXParameters(keyStore); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java index 7c10ad4d9..b589ec768 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java @@ -39,8 +39,10 @@ static byte[] calculateHash(byte[] nonce, @Nullable Certificate certificate) { if (certificate != null) { digest.update(certificate.getEncoded()); } else { - LOG.warn( - "No client certificate available. Cannot bind nonce to public key to prevent masquerading attack. TLS misconfiguration!"); + if (LOG.isWarnEnabled()) { + LOG.warn( + "No client certificate available. Cannot bind nonce to public key to prevent masquerading attack. TLS misconfiguration!"); + } } return digest.digest(); } catch (Exception e1) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java index 22890dcb2..333eff4f7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java @@ -17,10 +17,48 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +/** + * A TPM2d RatProver Driver implementation that proves its identity to a remote peer using TPM2d + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class TPM2dProver extends RatProverDriver { private static final Logger LOG = LoggerFactory.getLogger(TPM2dProver.class); + /* + * ******************* Protocol ******************* + * + * Verifier: (Challenger) + * ------------------------- + * Generate NonceV + * create RatChallenge (NonceV, aType, pcr_mask) + * ------------------------- + * + * Prover: (Responder) + * ------------------------- + * get RatChallenge (NonceV, aType, pcr_mask) + * hash = calculateHash(nonceV, certV) + * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) + * response = TPM2dToRemote = tpmSocket.attestationRequest(req) + * create AttestationResponse from tpm response + * ------------------------- + * + * Verifier: (Responder) + * ------------------------- + * get AttestationResponse + * hash = calculateHash(nonceV, certV) + * check signature(response, hash) + * check repo(aType, response, ttpUri) + * create RatResult + * ------------------------- + * + * Prover: (Requester) + * ------------------------- + * get AttestationResult + * ------------------------- + * + */ + private BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dProverConfig config = new Tpm2dProverConfig.Builder().build(); @@ -31,17 +69,23 @@ public TPM2dProver(){ @Override public void setConfig(Object config) { if (config instanceof Tpm2dProverConfig) { - LOG.debug("Set rat prover config"); + if (LOG.isDebugEnabled()) { + LOG.debug("Set rat prover config"); + } this.config = (Tpm2dProverConfig) config; } else { - LOG.warn("Invalid prover config"); + if (LOG.isWarnEnabled()) { + LOG.warn("Invalid prover config"); + } } } @Override public void delegate(IdscpMessage message) { queue.add(message); - LOG.debug("Delegated to prover"); + if (LOG.isDebugEnabled()) { + LOG.debug("Delegated to prover"); + } } @Override @@ -52,7 +96,9 @@ public void run() { IdscpMessage msg; try { msg = queue.take(); - LOG.debug("Prover receives new message"); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover receives new message"); + } } catch (InterruptedException e) { fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; @@ -61,7 +107,9 @@ public void run() { // check if message is from rat verifier if (!msg.hasIdscpRatVerifier()) { //unexpected message - LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } @@ -79,15 +127,21 @@ public void run() { // check if wrapper contains expected rat challenge if (!tpm2dMessageWrapper.hasRatChallenge()) { //unexpected message - LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatChallenge"); + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatChallenge"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } - LOG.debug("Get rat challenge from rat verifier"); + if (LOG.isDebugEnabled()) { + LOG.debug("Get rat challenge from rat verifier"); + } Tpm2dRatChallenge challenge = tpm2dMessageWrapper.getRatChallenge(); - LOG.debug("Requesting attestation from TPM ..."); + if (LOG.isDebugEnabled()) { + LOG.debug("Requesting attestation from TPM ..."); + } // hash byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), @@ -115,7 +169,9 @@ public void run() { byte[] response = TpmMessageFactory.getAttestationResponseMessage(tpmResponse) .toByteArray(); - LOG.debug("Send rat response to verifier"); + if (LOG.isDebugEnabled()) { + LOG.debug("Send rat response to verifier"); + } fsmListener.onRatProverMessage( InternalControlMessage.RAT_PROVER_MSG, IdscpMessageFactory.getIdscpRatProverMessage(response) @@ -124,7 +180,9 @@ public void run() { // wait for result try { msg = queue.take(); - LOG.debug("Prover receives new message"); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover receives new message"); + } } catch (InterruptedException e) { fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; @@ -133,7 +191,9 @@ public void run() { // check if message is from rat verifier if (!msg.hasIdscpRatVerifier()) { //unexpected message - LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } @@ -150,20 +210,28 @@ public void run() { // check if wrapper contains expected rat result if (!tpm2dMessageWrapper.hasRatResult()) { //unexpected message - LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResult"); + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResult"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } - LOG.debug("Get rat challenge from rat verifier"); + if (LOG.isDebugEnabled()) { + LOG.debug("Get rat challenge from rat verifier"); + } Tpm2dRatResult result = tpm2dMessageWrapper.getRatResult(); // notify fsm if (result.getResult()) { - LOG.debug("Attestation succeed"); + if (LOG.isDebugEnabled()) { + LOG.debug("Attestation succeed"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); } else { - LOG.warn("Attestation failed"); + if (LOG.isWarnEnabled()) { + LOG.warn("Attestation failed"); + } fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java index 6f3bd3ce9..68d868816 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java @@ -7,6 +7,9 @@ import java.io.IOException; import java.net.Socket; +/** + * A TPM2d Socket for communication with the Trusted Platform Module + */ public class TPM2dSocket extends Socket { private final DataInputStream is; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java index ce6ec98fd..3ecb83a2e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java @@ -30,9 +30,46 @@ import tss.tpm.TPMT_SIGNATURE; import tss.tpm.TPM_ALG_ID; +/** + * A TPM2d RatVerifier driver that verifies the remote peer's identity using TPM2d + */ public class TPM2dVerifier extends RatVerifierDriver { private static final Logger LOG = LoggerFactory.getLogger(TPM2dVerifier.class); + /* + * ******************* Protocol ******************* + * + * Verifier: (Challenger) + * ------------------------- + * Generate NonceV + * create RatChallenge (NonceV, aType, pcr_mask) + * ------------------------- + * + * Prover: (Responder) + * ------------------------- + * get RatChallenge (NonceV, aType, pcr_mask) + * hash = calculateHash(nonceV, certV) + * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) + * response = TPM2dToRemote = tpmSocket.attestationRequest(req) + * create AttestationResponse from tpm response + * ------------------------- + * + * Verifier: (Responder) + * ------------------------- + * get AttestationResponse + * hash = calculateHash(nonceV, certV) + * check signature(response, hash) + * check repo(aType, response, ttpUri) + * create RatResult + * ------------------------- + * + * Prover: (Requester) + * ------------------------- + * get AttestationResult + * ------------------------- + * + */ + private BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dVerifierConfig config = new Tpm2dVerifierConfig.Builder().build(); @@ -259,38 +296,4 @@ private boolean checkSignature(@NonNull Tpm2dRatResponse response, byte[] hash) return false; } } - - /* - * ******************* New Protocol ******************* - * - * Verifier: (Challenger) - * ------------------------- - * Generate NonceV - * create RatChallenge (NonceV, aType, pcr_mask) - * ------------------------- - * - * Prover: (Responder) - * ------------------------- - * get RatChallenge (NonceV, aType, pcr_mask) - * hash = calculateHash(nonceV, certV) - * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) - * response = TPM2dToRemote = tpmSocket.attestationRequest(req) - * create AttestationResponse from tpm response - * ------------------------- - * - * Verifier: (Responder) - * ------------------------- - * get AttestationResponse - * hash = calculateHash(nonceV, certV) - * check signature(response, hash) - * check repo(aType, response, ttpUri) - * create RatResult - * ------------------------- - * - * Prover: (Requester) - * ------------------------- - * get AttestationResult - * ------------------------- - * - */ } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java index 2a6e10c99..dd904d1f4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java @@ -3,6 +3,11 @@ import java.security.cert.Certificate; import org.checkerframework.checker.nullness.qual.NonNull; +/** + * A configuration class for TPM2d RatPriver driver + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class Tpm2dProverConfig { private Certificate remoteCertificate; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java index 07e8ded2e..9c5060b24 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java @@ -6,6 +6,11 @@ import java.security.cert.Certificate; import org.checkerframework.checker.nullness.qual.NonNull; +/** + * A configuration class for TPM2d RatVerifier Driver + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class Tpm2dVerifierConfig { private Certificate localCertificate; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java index 6c7818e58..a59a83ccd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java @@ -6,6 +6,11 @@ import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d.Code; import java.util.List; +/** + * A message factory for creating TPM2d RAT messages + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class TpmMessageFactory { static Tpm2dMessageWrapper getAttestationChallengeMessage( diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 276f75804..382c6e8ad 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -12,7 +12,9 @@ import java.util.concurrent.LinkedBlockingQueue; /** - * A RatProver dummy, that sends two incoming messages from the remote rat verifier and also sends two messages + * A RatProver dummy that exchanges rat messages with a remote RatVerifier + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class RatProverDummy extends RatProverDriver { private static final Logger LOG = LoggerFactory.getLogger(RatProverDummy.class); @@ -26,7 +28,9 @@ public RatProverDummy(){ @Override public void delegate(IdscpMessage message) { queue.add(message); - LOG.debug("Delegated to prover"); + if (LOG.isDebugEnabled()) { + LOG.debug("Delegated to prover"); + } } @Override @@ -37,9 +41,13 @@ public void run() { sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, IdscpMessageFactory.getIdscpRatProverMessage("test".getBytes())); - LOG.debug("Prover waits"); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover waits"); + } IDSCPv2.IdscpMessage m = queue.take(); - LOG.debug("Prover receives, send something"); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover receives, send something"); + } if (--countDown == 0) break; } catch (InterruptedException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index 879223b3c..c1293130a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -10,6 +10,11 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +/** + * A RatVerifier dummy that exchanges messages with a remote RatProver dummy + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ public class RatVerifierDummy extends RatVerifierDriver { private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDummy.class); @@ -22,7 +27,9 @@ public RatVerifierDummy(){ @Override public void delegate(IDSCPv2.IdscpMessage message) { queue.add(message); - LOG.debug("Delegated to Verifier"); + if (LOG.isDebugEnabled()) { + LOG.debug("Delegated to Verifier"); + } } @Override @@ -31,9 +38,13 @@ public void run(){ while (running){ try { sleep(1000); - LOG.debug("Verifier waits"); + if (LOG.isDebugEnabled()) { + LOG.debug("Verifier waits"); + } IDSCPv2.IdscpMessage m = queue.take(); - LOG.debug("Verifier receives, send something"); + if (LOG.isDebugEnabled()) { + LOG.debug("Verifier receives, send something"); + } fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, IdscpMessageFactory.getIdscpRatVerifierMessage("test".getBytes())); if (--countDown == 0) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index fa95f2418..f36547a3d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -23,6 +23,9 @@ public class NativeTLSDriver implements SecureChannelDriver { private static final Logger LOG = LoggerFactory.getLogger(NativeTLSDriver.class); + /* + * Asynchronous client connect to a TLS server + */ @Override public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { try { @@ -37,6 +40,11 @@ public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { } } + /* + * Starting TLS Server + * + * return null on failure + */ @Override public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, IdscpConnectionListener idscpServerCallback) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java index c99bbbc8b..6127dcd7a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java @@ -103,15 +103,16 @@ public static void verifyTlsSession(SSLSession sslSession) throws SSLPeerUnverif } } - //toDo localhost is matched manually to 127.0.0.1 for testing.. a matching file ip <-> dns - // would be nicer in the future - // automatic dns resolving via DNS service is not ann option since we cannot trust the DNS + //toDo localhost is matched manually to 127.0.0.1 for testing.. + // automatic dns resolving via DNS service is not an option since we cannot trust the DNS if (acceptedDnsNames.contains("localhost")) { acceptedIpAddresses.add("127.0.0.1"); } if (isIpAddress(host)) { + //FIXME The server should provide a possibility to validate clients dnsNames against SANs in + // Client certificate to avoid MITMs. This is an open issue //check ip addresses RFC 2818 (Section 3.1) if (!acceptedIpAddresses.contains(host)) { throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index d4cc82b43..b3a0ba1ec 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -13,7 +13,6 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class InputListenerThread extends Thread implements InputListener { - //private static final Logger LOG = LoggerFactory.getLogger(InputListenerThread.class); private DataInputStream in; private DataAvailableListener listener = null; //no race conditions, could be empty list diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index b1fd57995..d65d73453 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -21,29 +21,9 @@ import java.util.concurrent.CountDownLatch; /** - * A TLS Client that notifies an IDSCPv2Configuration when a secure channel was created and the TLS handshake is done - * The client is notified from an InputListenerThread when new data are available and transfer them to the - * SecureChannelListener - * - * Developer API - * - * constructors: - * TLSClient(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket and all TLS Security configurations like - * sslParameters (protocol, cipher, ..), trustStore, keyStore - * - * Methods: - * connect(String host, int port) connect the client asynchronous to the server and starts the TLS handshake - * - * close() disconnects the client - * - * - * handshakeCompleted() create a secureChannel, including this client; start inputListenerThread and transfer - * the secureChannel to the IDSCPv2Configuration - * - * send(byte[] data) send data to the server - * - * onMessage(int len, byte[] rawData) is a callback function for the InputListenerThread, that is called when new - * data are available. Transfer them to the SecureChannelListener + * A TLS Client that notifies an IDSCPv2Configuration when a secure channel was created and the + * TLS handshake is done. The client is notified from an InputListenerThread when new data are + * available and transfer it to the SecureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -89,6 +69,8 @@ public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) clientSocket = socketFactory.createSocket(); SSLSocket sslSocket = (SSLSocket) clientSocket; + + //set TLS constraints SSLParameters sslParameters = sslSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(false); //use server priority order sslParameters.setNeedClientAuth(true); @@ -100,6 +82,9 @@ public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) } + /* + * Connect to TLS server and start TLS Handshake + */ public void connect(String hostname, int port){ SSLSocket sslSocket = (SSLSocket) clientSocket; if (sslSocket == null || sslSocket.isClosed()){ @@ -221,6 +206,9 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) return; } + //Create secure channel, register secure channel as message listener and provide it to + // IDSCPv2 Configuration. + //Start Input Listener SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 10a07ba8c..e1171a82f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -17,19 +17,8 @@ import java.security.NoSuchAlgorithmException; /** - * A TLS Server that listens on a given port from the IDSCPv2Settings and create new TLSServerThreads for incoming - * connections - * - * Developer API - * - * constructors: - * TLSServer(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket and all TLS Security configurations like - * sslParameters (protocol, cipher, ..), trustStore, keyStore - * - * Methods: - * run() - * safeStop() - * isRunning() + * A TLS Server that listens on a given port from the IDSCPv2Settings and create new + * TLSServerThreads for incoming connections * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -80,6 +69,8 @@ public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, serverSocket.setSoTimeout(5000); SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; + + //set tls constraints SSLParameters sslParameters = sslServerSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite sslParameters.setNeedClientAuth(true); //client must authenticate diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index f7ddeadef..c2c3ddf9e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -18,25 +18,10 @@ import java.util.concurrent.CountDownLatch; /** - * A TLSServerThread that notifies an IDSCPv2Config when a secure channel was created and the TLS handshake is done - * When new data are available the serverThread transfers them to the SecureChannelListener + * A TLSServerThread that notifies an IDSCPv2Config when a secure channel was created and the + * TLS handshake is done * - * Developer API - * - * constructors: - * TLSServerThread(IDSCPv2Settings, IDSCPv2Callback) initializes the TLS Socket - * - * Methods: - * run() runs the serverThread and starts listening for new data - * - * close() disconnects the serverThread - * - * - * handshakeCompleted() create a secureChannel, including this serverThread and provides it to the IDSCPv2Config - * - * send(byte[] data) send data to the client - * - * onMessage(int len, byte[] rawData) is called when new data are available. Transfer them to the SecureChannelListener + * When new data are available the serverThread transfers it to the SecureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -203,6 +188,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) return; } + //provide secure channel to IDSCPv2 Config and register secure channel as listener SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java index 2fa4351ce..7a4d2ecee 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/DapsDriver.java @@ -14,6 +14,10 @@ public interface DapsDriver { /* * Verify a Daps token + * + * An optional security requirements object can be provided to validate the DAT body + * + * Return the number of seconds, the DAT is valid */ long verifyToken(byte[] dat, Object securityRequirements); } From f549bbed89590f3086140120002874e0b743adf9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 8 Apr 2020 21:26:32 +0200 Subject: [PATCH 063/237] Code cleanup of camel-ids --- .../WsConstants.java => IdscpConstants.java} | 11 +- ...Constants.java => WebSocketConstants.java} | 9 +- .../ids/camel/ids/client/WsComponent.java | 16 +- .../ids/camel/ids/client/WsEndpoint.java | 33 ++- .../ids/camel/ids/client/WsProducer.java | 2 +- .../ConnectionManagerService.java | 14 +- .../ids/camel/ids/server/ConnectorRef.java | 71 ----- .../server/DefaultNodeSynchronization.java | 4 +- ...tory.java => DefaultWebSocketFactory.java} | 13 +- .../camel/ids/server/DefaultWebsocket.java | 14 +- ...etStore.java => MemoryWebSocketStore.java} | 4 +- ...Component.java => WebSocketComponent.java} | 264 ++++-------------- ...et.java => WebSocketComponentServlet.java} | 29 +- ...etConsumer.java => WebSocketConsumer.java} | 15 +- ...etEndpoint.java => WebSocketEndpoint.java} | 54 ++-- .../camel/ids/server/WebSocketFactory.java | 2 +- ...etProducer.java => WebSocketProducer.java} | 28 +- ...er.java => WebSocketProducerConsumer.java} | 4 +- ...ebsocketStore.java => WebSocketStore.java} | 5 +- .../ids/server/WebsocketSendException.java | 1 + .../org/apache/camel/component/idsserver | 2 +- 21 files changed, 176 insertions(+), 419 deletions(-) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/{client/WsConstants.java => IdscpConstants.java} (73%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/{server/WebsocketConstants.java => WebSocketConstants.java} (81%) delete mode 100644 camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/ConnectorRef.java rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{DefaultWebsocketFactory.java => DefaultWebSocketFactory.java} (88%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{MemoryWebsocketStore.java => MemoryWebSocketStore.java} (94%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketComponent.java => WebSocketComponent.java} (69%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketComponentServlet.java => WebSocketComponentServlet.java} (72%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketConsumer.java => WebSocketConsumer.java} (85%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketEndpoint.java => WebSocketEndpoint.java} (86%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketProducer.java => WebSocketProducer.java} (77%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketProducerConsumer.java => WebSocketProducerConsumer.java} (91%) rename camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/{WebsocketStore.java => WebSocketStore.java} (95%) diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsConstants.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/IdscpConstants.java similarity index 73% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsConstants.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/IdscpConstants.java index 4d174c618..bc53fda9a 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsConstants.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/IdscpConstants.java @@ -17,17 +17,12 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.camel.ids.client; +package de.fhg.aisec.ids.camel.ids; /** */ -public final class WsConstants { - - public static final String CONTENT_TYPE_JAVA_SERIALIZED_OBJECT = - "application/x-java-serialized-object"; - public static final String CONTENT_TYPE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; - +public final class IdscpConstants { public static final String WS_PROTOCOL = "idsclientplain"; public static final String WSS_PROTOCOL = "idsclient"; - private WsConstants() {} + private IdscpConstants() {} } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConstants.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/WebSocketConstants.java similarity index 81% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConstants.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/WebSocketConstants.java index 6c1b28f8d..7fc982549 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConstants.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/WebSocketConstants.java @@ -17,18 +17,17 @@ * limitations under the License. * =========================LICENSE_END================================== */ -package de.fhg.aisec.ids.camel.ids.server; +package de.fhg.aisec.ids.camel.ids; -public final class WebsocketConstants { +public final class WebSocketConstants { - public static final int DEFAULT_PORT = 9292; + public static final String DEFAULT_PORT = "9292"; public static final String DEFAULT_HOST = "0.0.0.0"; public static final String CONNECTION_KEY = "websocket.connectionKey"; - public static final String SEND_TO_ALL = "websocket.sendToAll"; public static final String WS_PROTOCOL = "ws"; public static final String WSS_PROTOCOL = "wss"; - private WebsocketConstants() {} + private WebSocketConstants() {} } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsComponent.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsComponent.java index af1d6cf66..f23d9ebf5 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsComponent.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsComponent.java @@ -19,21 +19,21 @@ */ package de.fhg.aisec.ids.camel.ids.client; -import static de.fhg.aisec.ids.camel.ids.server.WebsocketConstants.WSS_PROTOCOL; -import static de.fhg.aisec.ids.camel.ids.server.WebsocketConstants.WS_PROTOCOL; - -import java.net.URI; +import de.fhg.aisec.ids.camel.ids.IdscpConstants; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import org.apache.camel.component.ahc.AhcComponent; import org.apache.camel.component.ahc.AhcEndpoint; +import java.net.URI; + public class WsComponent extends AhcComponent { @Override protected String createAddressUri(String uri, String remaining) { - if (uri.startsWith("idsclientplain:")) { - return uri.replaceFirst("idsclientplain", WS_PROTOCOL); - } else if (uri.startsWith("idsclient:")) { - return uri.replaceFirst("idsclient", WSS_PROTOCOL); + if (uri.startsWith(IdscpConstants.WSS_PROTOCOL + ":")) { + uri = uri.replaceFirst(IdscpConstants.WSS_PROTOCOL, WebSocketConstants.WSS_PROTOCOL); + } else if (uri.startsWith(IdscpConstants.WS_PROTOCOL + ":")) { + uri = uri.replaceFirst(IdscpConstants.WS_PROTOCOL, WebSocketConstants.WS_PROTOCOL); } // Should not happen return uri; diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsEndpoint.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsEndpoint.java index bb5c168dc..5f71f1519 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsEndpoint.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsEndpoint.java @@ -23,8 +23,9 @@ import de.fhg.aisec.ids.api.infomodel.InfoModel; import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.camel.ids.CamelComponent; +import de.fhg.aisec.ids.camel.ids.IdscpConstants; import de.fhg.aisec.ids.camel.ids.ProxyX509TrustManager; -import de.fhg.aisec.ids.camel.ids.server.WebsocketConstants; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import de.fhg.aisec.ids.comm.CertificatePair; import de.fhg.aisec.ids.comm.client.ClientConfiguration; import de.fhg.aisec.ids.comm.client.IdspClientSocket; @@ -66,18 +67,17 @@ extendsScheme = "ahc,ahc", title = "IDS Protocol", syntax = "idsclient:httpUri", - consumerClass = WsConsumer.class, label = "websocket" ) public class WsEndpoint extends AhcEndpoint { private static final Logger LOG = LoggerFactory.getLogger(WsEndpoint.class); - private static List outgoingConnections = new ArrayList<>(); + private static final List outgoingConnections = new ArrayList<>(); private final Set consumers = new HashSet<>(); private final WsListener listener = new WsListener(consumers, this); private WebSocket websocket; - private CertificatePair certificatePair = new CertificatePair(); + private final CertificatePair certificatePair = new CertificatePair(); @UriParam(label = "producer") private boolean useStreaming; @@ -144,6 +144,7 @@ WebSocket getWebSocket() { return websocket; } + @SuppressWarnings("unused") void setWebSocket(WebSocket websocket) { this.websocket = websocket; } @@ -153,6 +154,7 @@ public boolean isUseStreaming() { } /** To enable streaming to send data as multiple text fragments. */ + @SuppressWarnings("unused") public void setUseStreaming(boolean useStreaming) { this.useStreaming = useStreaming; } @@ -161,6 +163,7 @@ public boolean isSendMessageOnError() { return sendMessageOnError; } + @SuppressWarnings("unused") public void setAttestation(int type) { this.attestation = type; } @@ -169,6 +172,7 @@ public int getAttestation() { return attestation; } + @SuppressWarnings("unused") public void setAttestationMask(int type) { this.attestationMask = type; } @@ -178,6 +182,7 @@ public int getAttestationMask() { } /** Whether to send an message if the web-socket listener received an error. */ + @SuppressWarnings("unused") public void setSendMessageOnError(boolean sendMessageOnError) { this.sendMessageOnError = sendMessageOnError; } @@ -192,10 +197,10 @@ protected AsyncHttpClient createClient(AsyncHttpClientConfig config) { public void connect() { String uri = getHttpUri().toASCIIString(); - if (uri.startsWith("idsclient:")) { - uri = uri.replaceFirst("idsclient", WebsocketConstants.WSS_PROTOCOL); - } else if (uri.startsWith("idsclientplain:")) { - uri = uri.replaceFirst("idsclientplain", WebsocketConstants.WS_PROTOCOL); + if (uri.startsWith(IdscpConstants.WSS_PROTOCOL + ":")) { + uri = uri.replaceFirst(IdscpConstants.WSS_PROTOCOL, WebSocketConstants.WSS_PROTOCOL); + } else if (uri.startsWith(IdscpConstants.WS_PROTOCOL + ":")) { + uri = uri.replaceFirst(IdscpConstants.WS_PROTOCOL, WebSocketConstants.WS_PROTOCOL); } LOG.debug("Connecting to {}", uri); @@ -205,6 +210,12 @@ public void connect() { LOG.debug("remote-attestation mode: {}", this.getAttestation()); LOG.debug("remote-attestation mask: {}", this.getAttestationMask()); + IdsAttestationType attestationType = IdsAttestationType.forNumber(this.getAttestation()); + if (attestationType == null) { + throw new RuntimeException("Error: " + this.getAttestation() + + " does not seem to be a valid attestation type, aborting"); + } + // Execute IDS protocol immediately after connect Settings settings = CamelComponent.getSettings(); URI ttpUri = null; @@ -220,10 +231,14 @@ public void connect() { } catch (URISyntaxException e) { LOG.error("incorrect TTP URI syntax", e); } + if (ttpUri == null) { + throw new RuntimeException("Error: ttpUri required, aborting!"); + } + InfoModel infoModelManager = CamelComponent.getInfoModelManager(); ClientConfiguration.Builder clientConfigBuilder = new ClientConfiguration.Builder() - .attestationType(IdsAttestationType.forNumber(this.getAttestation())) + .attestationType(attestationType) .attestationMask(this.getAttestationMask()) .certificatePair(certificatePair) .ttpUrl(ttpUri); diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsProducer.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsProducer.java index 0301aec74..6843941ce 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsProducer.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/client/WsProducer.java @@ -31,7 +31,7 @@ public class WsProducer extends DefaultProducer { private static final int DEFAULT_STREAM_BUFFER_SIZE = 127; - private int streamBufferSize = DEFAULT_STREAM_BUFFER_SIZE; + private final int streamBufferSize = DEFAULT_STREAM_BUFFER_SIZE; public WsProducer(WsEndpoint endpoint) { super(endpoint); diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/connectionmanagement/ConnectionManagerService.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/connectionmanagement/ConnectionManagerService.java index 78d7a4ae2..fd9f51727 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/connectionmanagement/ConnectionManagerService.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/connectionmanagement/ConnectionManagerService.java @@ -23,14 +23,14 @@ import de.fhg.aisec.ids.api.conm.IDSCPIncomingConnection; import de.fhg.aisec.ids.api.conm.IDSCPOutgoingConnection; import de.fhg.aisec.ids.api.conm.IDSCPServerEndpoint; -import de.fhg.aisec.ids.api.settings.Settings; import de.fhg.aisec.ids.camel.ids.client.WsEndpoint; -import de.fhg.aisec.ids.camel.ids.server.WebsocketComponent; -import de.fhg.aisec.ids.camel.ids.server.WebsocketComponentServlet; +import de.fhg.aisec.ids.camel.ids.server.WebSocketComponent; +import de.fhg.aisec.ids.camel.ids.server.WebSocketComponentServlet; +import org.osgi.service.component.annotations.Component; + import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.osgi.service.component.annotations.*; /** * Main entry point of the Connection Management Layer. @@ -45,7 +45,7 @@ public class ConnectionManagerService implements ConnectionManager { @Override public List listAvailableEndpoints() { - return WebsocketComponent.getConnectors() + return WebSocketComponent.getConnectors() .entrySet() .stream() .map( @@ -62,12 +62,12 @@ public List listAvailableEndpoints() { @Override public List listIncomingConnections() { - return WebsocketComponent.getConnectors() + return WebSocketComponent.getConnectors() .values() .stream() .flatMap( connectorRef -> { - WebsocketComponentServlet servlet = connectorRef.getServlet(); + WebSocketComponentServlet servlet = connectorRef.getServlet(); // Servlet only present if an incoming connection exists. If null, do not collect // consumer information. if (servlet != null) { diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/ConnectorRef.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/ConnectorRef.java deleted file mode 100644 index f2b2318fd..000000000 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/ConnectorRef.java +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * camel-ids - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.camel.ids.server; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; - -public class ConnectorRef { - Server server; - ServerConnector connector; - WebsocketComponentServlet servlet; - MemoryWebsocketStore memoryStore; - int refCount; - - ConnectorRef( - Server server, - ServerConnector connector, - WebsocketComponentServlet servlet, - MemoryWebsocketStore memoryStore) { - this.server = server; - this.connector = connector; - this.servlet = servlet; - this.memoryStore = memoryStore; - increment(); - } - - public int increment() { - return ++refCount; - } - - public int decrement() { - return --refCount; - } - - public int getRefCount() { - return refCount; - } - - public Server getServer() { - return this.server; - } - - public ServerConnector getConnector() { - return this.connector; - } - - public WebsocketComponentServlet getServlet() { - return this.servlet; - } - - public MemoryWebsocketStore getMemoryStore() { - return this.memoryStore; - } -} diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultNodeSynchronization.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultNodeSynchronization.java index 78a120ba8..61b5cae9d 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultNodeSynchronization.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultNodeSynchronization.java @@ -21,9 +21,9 @@ public class DefaultNodeSynchronization implements NodeSynchronization { - private final WebsocketStore memoryStore; + private final WebSocketStore memoryStore; - public DefaultNodeSynchronization(WebsocketStore memoryStore) { + public DefaultNodeSynchronization(WebSocketStore memoryStore) { this.memoryStore = memoryStore; } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocketFactory.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebSocketFactory.java similarity index 88% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocketFactory.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebSocketFactory.java index 9390dc193..af5a0d45e 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocketFactory.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebSocketFactory.java @@ -20,18 +20,19 @@ package de.fhg.aisec.ids.camel.ids.server; import de.fhg.aisec.ids.comm.CertificatePair; -import java.security.cert.X509Certificate; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** Default websocket factory. Used when no custom websocket is needed. */ -public class DefaultWebsocketFactory implements WebSocketFactory { - private static final Logger LOG = LoggerFactory.getLogger(DefaultWebsocketFactory.class); +import java.security.cert.X509Certificate; + +/** Default WebSocket factory. Used when no custom WebSocket is needed. */ +public class DefaultWebSocketFactory implements WebSocketFactory { + private static final Logger LOG = LoggerFactory.getLogger(DefaultWebSocketFactory.class); private final CertificatePair certificatePair; - public DefaultWebsocketFactory(CertificatePair certificatePair) { + public DefaultWebSocketFactory(CertificatePair certificatePair) { this.certificatePair = certificatePair; } @@ -41,7 +42,7 @@ public DefaultWebsocket newInstance( String protocol, String pathSpec, NodeSynchronization sync, - WebsocketConsumer consumer) { + WebSocketConsumer consumer) { // Create final, complete pair from the local (server) certificate ... CertificatePair finalPair = new CertificatePair(certificatePair); // ... plus the remote (client) certificate from the request diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java index d55f1e50f..5e9691df0 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java @@ -26,9 +26,9 @@ import de.fhg.aisec.ids.api.infomodel.InfoModel; import de.fhg.aisec.ids.api.settings.ConnectionSettings; import de.fhg.aisec.ids.api.settings.Settings; +import de.fhg.aisec.ids.api.tokenm.DatException; import de.fhg.aisec.ids.api.tokenm.TokenManager; import de.fhg.aisec.ids.camel.ids.CamelComponent; -import de.fhg.aisec.ids.api.tokenm.DatException; import de.fhg.aisec.ids.comm.CertificatePair; import de.fhg.aisec.ids.comm.server.ServerConfiguration; import de.fhg.aisec.ids.comm.ws.protocol.ProtocolState; @@ -54,19 +54,18 @@ public class DefaultWebsocket implements EndpointConfigListener { private static final Logger LOG = LoggerFactory.getLogger(DefaultWebsocket.class); - private final WebsocketConsumer consumer; + private final WebSocketConsumer consumer; private final NodeSynchronization sync; private Session session; private String connectionKey; private final String pathSpec; private FSM idsFsm; - private CertificatePair certificatePair; - private boolean isTokenValidated = false; + private final CertificatePair certificatePair; public DefaultWebsocket( NodeSynchronization sync, String pathSpec, - WebsocketConsumer consumer, + WebSocketConsumer consumer, CertificatePair certificatePair) { this.sync = sync; this.consumer = consumer; @@ -281,11 +280,6 @@ public String getRemoteHostname() { // Observer update function, that is called by the subject when endpoint settings have changed @Override public void updateTokenValidation() { - if (!isTokenValidated) { - // Not relevant because initial validation was not successful yet - return; - } - if (LOG.isInfoEnabled()) { LOG.info("Endpoint config for endpoint {}:{} has changed. Verify DynamicAttributeToken again", consumer.getEndpoint().getHost(), consumer.getEndpoint().getPort()); diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebsocketStore.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebSocketStore.java similarity index 94% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebsocketStore.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebSocketStore.java index e4e4b9a36..8ef11e26d 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebsocketStore.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/MemoryWebSocketStore.java @@ -22,8 +22,8 @@ import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; -public class MemoryWebsocketStore extends ConcurrentHashMap - implements WebsocketStore { +public class MemoryWebSocketStore extends ConcurrentHashMap + implements WebSocketStore { private static final long serialVersionUID = -2826843758230613922L; diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponent.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponent.java similarity index 69% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponent.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponent.java index 59e451d88..b436918ad 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponent.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponent.java @@ -20,6 +20,7 @@ package de.fhg.aisec.ids.camel.ids.server; import de.fhg.aisec.ids.camel.ids.ProxyX509TrustManager; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import de.fhg.aisec.ids.comm.CertificatePair; import org.apache.camel.Endpoint; import org.apache.camel.RuntimeCamelException; @@ -27,17 +28,18 @@ import org.apache.camel.spi.Metadata; import org.apache.camel.support.DefaultComponent; import org.apache.camel.support.jsse.SSLContextParameters; -import org.eclipse.jetty.server.*; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlets.CrossOriginFilter; -import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ThreadPool; @@ -53,8 +55,8 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -public class WebsocketComponent extends DefaultComponent implements SSLContextParametersAware { - protected static final Logger LOG = LoggerFactory.getLogger(WebsocketComponent.class); +public class WebSocketComponent extends DefaultComponent implements SSLContextParametersAware { + protected static final Logger LOG = LoggerFactory.getLogger(WebSocketComponent.class); protected static final Map CONNECTORS = new HashMap<>(); protected Map socketFactories; @@ -69,8 +71,8 @@ public class WebsocketComponent extends DefaultComponent implements SSLContextPa @Metadata(label = "advanced") protected ThreadPool threadPool; - @Metadata(defaultValue = "9292") - protected Integer port = 9292; + @Metadata(defaultValue = WebSocketConstants.DEFAULT_PORT) + protected Integer port = Integer.parseInt(WebSocketConstants.DEFAULT_PORT); @Metadata(label = "advanced") protected Integer minThreads; @@ -78,47 +80,35 @@ public class WebsocketComponent extends DefaultComponent implements SSLContextPa @Metadata(label = "advanced") protected Integer maxThreads; - @Metadata(defaultValue = "0.0.0.0") - protected String host = "0.0.0.0"; - - @Metadata(label = "consumer") - protected String staticResources; - - @Metadata(label = "security", secret = true) - protected String sslKeyPassword; - - @Metadata(label = "security", secret = true) - protected String sslPassword; - - @Metadata(label = "security", secret = true) - protected String sslKeystore; + @Metadata(defaultValue = WebSocketConstants.DEFAULT_HOST) + protected String host = WebSocketConstants.DEFAULT_HOST; /** - * Map for storing servlets. {@link WebsocketComponentServlet} is identified by pathSpec {@link + * Map for storing servlets. {@link WebSocketComponentServlet} is identified by pathSpec {@link * String}. */ - private Map servlets = new HashMap<>(); + private final Map servlets = new HashMap<>(); - public class ConnectorRef { + public static class ConnectorRef { Server server; ServerConnector connector; - WebsocketComponentServlet servlet; - MemoryWebsocketStore memoryStore; + WebSocketComponentServlet servlet; + MemoryWebSocketStore memoryStore; AtomicInteger refCount = new AtomicInteger(1); ConnectorRef( Server server, ServerConnector connector, - WebsocketComponentServlet servlet, - MemoryWebsocketStore memoryStore) { + WebSocketComponentServlet servlet, + MemoryWebSocketStore memoryStore) { this.server = server; this.connector = connector; this.servlet = servlet; this.memoryStore = memoryStore; } - public int increment() { - return refCount.incrementAndGet(); + public void increment() { + refCount.incrementAndGet(); } public int decrement() { @@ -129,11 +119,11 @@ public int getRefCount() { return refCount.get(); } - public MemoryWebsocketStore getMemoryStore() { + public MemoryWebSocketStore getMemoryStore() { return memoryStore; } - public WebsocketComponentServlet getServlet() { + public WebSocketComponentServlet getServlet() { return servlet; } @@ -142,15 +132,15 @@ public ServerConnector getConnector() { } } - public WebsocketComponent() { + public WebSocketComponent() { this.setUseGlobalSslContextParameters(true); // this will automatically set up the ids handler factory this.setSocketFactories(new HashMap<>()); } /** Connects the URL specified on the endpoint to the specified processor. */ - public void connect(WebsocketProducerConsumer prodcon) throws Exception { - WebsocketEndpoint endpoint = prodcon.getEndpoint(); + public void connect(WebSocketProducerConsumer prodcon) throws Exception { + WebSocketEndpoint endpoint = prodcon.getEndpoint(); String connectorKey = getConnectorKey(endpoint); @@ -187,7 +177,7 @@ public void connect(WebsocketProducerConsumer prodcon) throws Exception { // Apply CORS (http://www.w3.org/TR/cors/) applyCrossOriginFiltering(endpoint, context); - MemoryWebsocketStore memoryStore = new MemoryWebsocketStore(); + MemoryWebSocketStore memoryStore = new MemoryWebSocketStore(); // Don't provide a Servlet object as Producer/Consumer will create them later on connectorRef = new ConnectorRef(server, connector, null, memoryStore); @@ -201,7 +191,6 @@ public void connect(WebsocketProducerConsumer prodcon) throws Exception { connectorRef.server.start(); CONNECTORS.put(connectorKey, connectorRef); - } else { connectorRef.increment(); } @@ -212,26 +201,24 @@ public void connect(WebsocketProducerConsumer prodcon) throws Exception { } NodeSynchronization sync = new DefaultNodeSynchronization(connectorRef.memoryStore); - WebsocketComponentServlet servlet = addServlet(sync, prodcon, endpoint.getResourceUri()); - if (prodcon instanceof WebsocketConsumer) { - WebsocketConsumer consumer = (WebsocketConsumer) prodcon; + WebSocketComponentServlet servlet = addServlet(sync, prodcon, endpoint.getResourceUri()); + if (prodcon instanceof WebSocketConsumer) { + WebSocketConsumer consumer = (WebSocketConsumer) prodcon; if (servlet.getConsumer() == null) { servlet.setConsumer(consumer); } - // register the consumer here - servlet.connect(consumer); } - if (prodcon instanceof WebsocketProducer) { - WebsocketProducer producer = (WebsocketProducer) prodcon; + if (prodcon instanceof WebSocketProducer) { + WebSocketProducer producer = (WebSocketProducer) prodcon; producer.setStore(connectorRef.memoryStore); } } } /** Disconnects the URL specified on the endpoint from the specified processor. */ - public void disconnect(WebsocketProducerConsumer prodcon) throws Exception { + public void disconnect(WebSocketProducerConsumer prodcon) throws Exception { // If the connector is not needed anymore then stop it - WebsocketEndpoint endpoint = prodcon.getEndpoint(); + WebSocketEndpoint endpoint = prodcon.getEndpoint(); String connectorKey = getConnectorKey(endpoint); synchronized (CONNECTORS) { @@ -254,11 +241,8 @@ public void disconnect(WebsocketProducerConsumer prodcon) throws Exception { // Camel controls the lifecycle of these entities so remove the // registered MBeans when Camel is done with the managed objects. } - if (prodcon instanceof WebsocketConsumer) { - connectorRef.servlet.disconnect((WebsocketConsumer) prodcon); - } - if (prodcon instanceof WebsocketProducer) { - ((WebsocketProducer) prodcon).setStore(null); + if (prodcon instanceof WebSocketProducer) { + ((WebSocketProducer) prodcon).setStore(null); } } } @@ -274,7 +258,7 @@ protected Endpoint createEndpoint(String uri, String remaining, Map>> Protocol found: {}, and resource: {}", resources[0], resources[1]); - } - - if (resources[0].equals("classpath")) { - context.setBaseResource( - new JettyClassPathResource(getCamelContext().getClassResolver(), resources[1])); - } else if (resources[0].equals("file")) { - context.setBaseResource(Resource.newResource(resources[1])); - } - DefaultServlet defaultServlet = new DefaultServlet(); - ServletHolder holder = new ServletHolder(defaultServlet); - - // avoid file locking on windows - // http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages - holder.setInitParameter("useFileMappedBuffer", "false"); - context.addServlet(holder, "/"); - } - - server.setHandler(context); - - return server; - } - - protected Server createStaticResourcesServer( - ServletContextHandler context, String host, int port, String home) throws Exception { - Server server = new Server(); - HttpConfiguration httpConfig = new HttpConfiguration(); - ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig)); - connector.setHost(host); - connector.setPort(port); - server.addConnector(connector); - return createStaticResourcesServer(server, context, home); - } - - protected WebsocketComponentServlet addServlet( - NodeSynchronization sync, WebsocketProducerConsumer prodcon, String resourceUri) + protected WebSocketComponentServlet addServlet( + NodeSynchronization sync, WebSocketProducerConsumer prodcon, String resourceUri) throws Exception { // Get Connector from one of the Jetty Instances to add WebSocket Servlet - WebsocketEndpoint endpoint = prodcon.getEndpoint(); + WebSocketEndpoint endpoint = prodcon.getEndpoint(); String key = getConnectorKey(endpoint); ConnectorRef connectorRef = getConnectors().get(key); - WebsocketComponentServlet servlet; + WebSocketComponentServlet servlet; if (connectorRef != null) { String pathSpec = createPathSpec(resourceUri); @@ -433,13 +372,13 @@ protected WebsocketComponentServlet addServlet( } } - protected WebsocketComponentServlet createServlet( + protected WebSocketComponentServlet createServlet( NodeSynchronization sync, String pathSpec, - Map servlets, + Map servlets, ServletContextHandler handler) { - WebsocketComponentServlet servlet = - new WebsocketComponentServlet(sync, pathSpec, getSocketFactories()); + WebSocketComponentServlet servlet = + new WebSocketComponentServlet(sync, pathSpec, getSocketFactories()); servlets.put(pathSpec, servlet); ServletHolder servletHolder = new ServletHolder(servlet); servletHolder.getInitParameters().putAll(handler.getInitParams()); @@ -498,7 +437,7 @@ private ServerConnector getSocketConnector( try { ProxyX509TrustManager.bindCertificatePair(sslContextParameters, true, certificatePair); } catch (GeneralSecurityException | IOException e) { - LOG.error("Failed to patch TrustManager for WebsocketComponent", e); + LOG.error("Failed to patch TrustManager for WebSocketComponent", e); } SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setSslContext(sslContextParameters.createSSLContext(getCamelContext())); @@ -538,12 +477,12 @@ private String extractHostName(String remaining) { } } - private static String getConnectorKey(WebsocketEndpoint endpoint) { + private static String getConnectorKey(WebSocketEndpoint endpoint) { return endpoint.getProtocol() + ":" + endpoint.getHost() + ":" + endpoint.getPort(); } private void applyCrossOriginFiltering( - WebsocketEndpoint endpoint, ServletContextHandler context) { + WebSocketEndpoint endpoint, ServletContextHandler context) { if (endpoint.isCrossOriginFilterOn()) { FilterHolder filterHolder = new FilterHolder(); CrossOriginFilter filter = new CrossOriginFilter(); @@ -554,119 +493,14 @@ private void applyCrossOriginFiltering( } } - // Properties - // ------------------------------------------------------------------------- - - public String getStaticResources() { - return staticResources; - } - - /** - * Set a resource path for static resources (such as .html files etc). - * - *

The resources can be loaded from classpath, if you prefix with classpath:, - * otherwise the resources is loaded from file system or from JAR files. - * - *

For example to load from root classpath use classpath:., or - * classpath:WEB-INF/static - * - *

If not configured (eg null) then no static resource is in use. - */ - public void setStaticResources(String staticResources) { - this.staticResources = staticResources; - } - - public String getHost() { - return host; - } - - /** The hostname. The default value is 0.0.0.0 */ - public void setHost(String host) { - this.host = host; - } - - public Integer getPort() { - return port; - } - - /** The port number. The default value is 9292 */ - public void setPort(Integer port) { - this.port = port; - } - - public String getSslKeyPassword() { - return sslKeyPassword; - } - - public String getSslPassword() { - return sslPassword; - } - - public String getSslKeystore() { - return sslKeystore; - } - - /** The password for the keystore when using SSL. */ - public void setSslKeyPassword(String sslKeyPassword) { - this.sslKeyPassword = sslKeyPassword; - } - - /** The password when using SSL. */ - public void setSslPassword(String sslPassword) { - this.sslPassword = sslPassword; - } - - /** The path to the keystore. */ - public void setSslKeystore(String sslKeystore) { - this.sslKeystore = sslKeystore; - } - - public Integer getMinThreads() { - return minThreads; - } - - /** - * To set a value for minimum number of threads in server thread pool. MaxThreads/minThreads or - * threadPool fields are required due to switch to Jetty9. The default values for minThreads is 1. - */ - public void setMinThreads(Integer minThreads) { - this.minThreads = minThreads; - } - - public Integer getMaxThreads() { - return maxThreads; - } - - /** - * To set a value for maximum number of threads in server thread pool. MaxThreads/minThreads or - * threadPool fields are required due to switch to Jetty9. The default values for maxThreads is 1 - * + 2 * noCores. - */ - public void setMaxThreads(Integer maxThreads) { - this.maxThreads = maxThreads; - } - public ThreadPool getThreadPool() { return threadPool; } - /** - * To use a custom thread pool for the server. MaxThreads/minThreads or threadPool fields are - * required due to switch to Jetty9. - */ - public void setThreadPool(ThreadPool threadPool) { - this.threadPool = threadPool; - } - public SSLContextParameters getSslContextParameters() { return sslContextParameters; } - /** To configure security using SSLContextParameters */ - public void setSslContextParameters(SSLContextParameters sslContextParameters) { - this.sslContextParameters = sslContextParameters; - } - @Override public boolean isUseGlobalSslContextParameters() { return this.useGlobalSslContextParameters; @@ -692,7 +526,7 @@ public void setSocketFactories(Map socketFactories) { this.socketFactories = socketFactories; if (!this.socketFactories.containsKey("ids")) { - this.socketFactories.put("ids", new DefaultWebsocketFactory(certificatePair)); + this.socketFactories.put("ids", new DefaultWebSocketFactory(certificatePair)); } } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponentServlet.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponentServlet.java similarity index 72% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponentServlet.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponentServlet.java index 9b1486d34..35e4fe787 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketComponentServlet.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketComponentServlet.java @@ -19,51 +19,38 @@ */ package de.fhg.aisec.ids.camel.ids.server; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class WebsocketComponentServlet extends WebSocketServlet { +import java.util.Map; + +public class WebSocketComponentServlet extends WebSocketServlet { private static final long serialVersionUID = 1L; - private static final Logger LOG = LoggerFactory.getLogger(WebsocketComponentServlet.class); + private static final Logger LOG = LoggerFactory.getLogger(WebSocketComponentServlet.class); private final NodeSynchronization sync; private final Map socketFactories; private final String pathSpec; - private WebsocketConsumer consumer; - private static final ConcurrentMap consumers = - new ConcurrentHashMap<>(); + private WebSocketConsumer consumer; - public WebsocketComponentServlet( + public WebSocketComponentServlet( NodeSynchronization sync, String pathSpec, Map socketFactories) { this.sync = sync; this.socketFactories = socketFactories; this.pathSpec = pathSpec; } - public WebsocketConsumer getConsumer() { + public WebSocketConsumer getConsumer() { return consumer; } - public void setConsumer(WebsocketConsumer consumer) { + public void setConsumer(WebSocketConsumer consumer) { this.consumer = consumer; } - public void connect(WebsocketConsumer consumer) { - LOG.debug("Connecting consumer: {}", consumer); - consumers.put(consumer.getPath(), consumer); - } - - public void disconnect(WebsocketConsumer consumer) { - LOG.debug("Disconnecting consumer: {}", consumer); - consumers.remove(consumer.getPath()); - } - @Override public void configure(WebSocketServletFactory factory) { factory.setCreator( diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConsumer.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketConsumer.java similarity index 85% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConsumer.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketConsumer.java index 89d62610e..b6368d743 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketConsumer.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketConsumer.java @@ -19,15 +19,16 @@ */ package de.fhg.aisec.ids.camel.ids.server; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.support.DefaultConsumer; -public class WebsocketConsumer extends DefaultConsumer implements WebsocketProducerConsumer { +public class WebSocketConsumer extends DefaultConsumer implements WebSocketProducerConsumer { - private final WebsocketEndpoint endpoint; + private final WebSocketEndpoint endpoint; - public WebsocketConsumer(WebsocketEndpoint endpoint, Processor processor) { + public WebSocketConsumer(WebSocketEndpoint endpoint, Processor processor) { super(endpoint, processor); this.endpoint = endpoint; } @@ -44,14 +45,10 @@ public void doStop() throws Exception { super.doStop(); } - public WebsocketEndpoint getEndpoint() { + public WebSocketEndpoint getEndpoint() { return endpoint; } - public String getPath() { - return endpoint.getPath(); - } - public int getAttestationType() { return endpoint.getAttestation(); } @@ -69,7 +66,7 @@ public void sendMessage(final String connectionKey, final Object message) { final Exchange exchange = getEndpoint().createExchange(); // set header and body - exchange.getIn().setHeader(WebsocketConstants.CONNECTION_KEY, connectionKey); + exchange.getIn().setHeader(WebSocketConstants.CONNECTION_KEY, connectionKey); exchange.getIn().setBody(message); // send exchange using the async routing engine diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketEndpoint.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketEndpoint.java similarity index 86% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketEndpoint.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketEndpoint.java index ac46d7b3f..ff6f360d2 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketEndpoint.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketEndpoint.java @@ -19,6 +19,7 @@ */ package de.fhg.aisec.ids.camel.ids.server; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; @@ -34,7 +35,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.List; -import java.util.Map; /** * The websocket component provides websocket endpoints for communicating with clients using @@ -46,19 +46,18 @@ scheme = "idsserver", title = "IDS Server Socket", syntax = "idsserver:host:port/resourceUri", - consumerClass = WebsocketConsumer.class, label = "idsserver" ) -public class WebsocketEndpoint extends DefaultEndpoint { +public class WebSocketEndpoint extends DefaultEndpoint { - private WebsocketComponent component; - private URI uri; + private final WebSocketComponent component; + private final URI uri; private List handlers; - @UriPath(defaultValue = "0.0.0.0") + @UriPath(defaultValue = WebSocketConstants.DEFAULT_HOST) private String host; - @UriPath(defaultValue = "9292") + @UriPath(defaultValue = WebSocketConstants.DEFAULT_PORT) private Integer port; @UriPath @@ -117,11 +116,10 @@ public class WebsocketEndpoint extends DefaultEndpoint { ) private Integer attestationMask = 0; - public WebsocketEndpoint( - WebsocketComponent component, - String uri, - String resourceUri, - Map parameters) { + public WebSocketEndpoint( + WebSocketComponent component, + String uri, + String resourceUri) { super(uri, component); this.resourceUri = resourceUri; this.component = component; @@ -133,37 +131,37 @@ public WebsocketEndpoint( } @Override - public WebsocketComponent getComponent() { + public WebSocketComponent getComponent() { ObjectHelper.notNull(component, "component"); - return (WebsocketComponent) super.getComponent(); + return (WebSocketComponent) super.getComponent(); } @Override public Consumer createConsumer(Processor processor) throws Exception { ObjectHelper.notNull(component, "component"); - WebsocketConsumer consumer = new WebsocketConsumer(this, processor); + WebSocketConsumer consumer = new WebSocketConsumer(this, processor); configureConsumer(consumer); return consumer; } @Override public Producer createProducer() { - return new WebsocketProducer(this); + return new WebSocketProducer(this); } - public void connect(WebsocketConsumer consumer) throws Exception { + public void connect(WebSocketConsumer consumer) throws Exception { component.connect(consumer); } - public void disconnect(WebsocketConsumer consumer) throws Exception { + public void disconnect(WebSocketConsumer consumer) throws Exception { component.disconnect(consumer); } - public void connect(WebsocketProducer producer) throws Exception { + public void connect(WebSocketProducer producer) throws Exception { component.connect(producer); } - public void disconnect(WebsocketProducer producer) throws Exception { + public void disconnect(WebSocketProducer producer) throws Exception { component.disconnect(producer); } @@ -172,6 +170,7 @@ public boolean isSingleton() { return true; } + @SuppressWarnings("unused") public URI getUri() { return uri; } @@ -208,6 +207,7 @@ public Integer getSendTimeout() { * Timeout in millis when sending to a websocket channel. The default timeout is 30000 (30 * seconds). */ + @SuppressWarnings("unused") public void setSendTimeout(Integer sendTimeout) { this.sendTimeout = sendTimeout; } @@ -216,11 +216,13 @@ public String getProtocol() { return uri.getScheme(); } + @SuppressWarnings("unused") public String getPath() { return uri.getPath(); } /** Whether to enable session support which enables HttpSession for each http request. */ + @SuppressWarnings("unused") public void setSessionSupport(boolean support) { sessionSupport = support; } @@ -237,6 +239,7 @@ public int getAttestation() { return attestation; } + @SuppressWarnings("unused") public void setAttestation(int i) { attestation = i; } @@ -245,6 +248,7 @@ public int getAttestationMask() { return attestationMask; } + @SuppressWarnings("unused") public void setAttestationMask(int i) { attestationMask = i; } @@ -253,6 +257,7 @@ public void setAttestationMask(int i) { * Set the buffer size of the websocketServlet, which is also the max frame byte size (default * 8192) */ + @SuppressWarnings("unused") public void setBufferSize(Integer bufferSize) { this.bufferSize = bufferSize; } @@ -265,6 +270,7 @@ public Integer getMaxIdleTime() { * Set the time in ms that the websocket created by the websocketServlet may be idle before * closing. (default is 300000) */ + @SuppressWarnings("unused") public void setMaxIdleTime(Integer maxIdleTime) { this.maxIdleTime = maxIdleTime; } @@ -277,6 +283,7 @@ public Integer getMaxTextMessageSize() { * Can be used to set the size in characters that the websocket created by the websocketServlet * may be accept before closing. */ + @SuppressWarnings("unused") public void setMaxTextMessageSize(Integer maxTextMessageSize) { this.maxTextMessageSize = maxTextMessageSize; } @@ -289,6 +296,7 @@ public Integer getMaxBinaryMessageSize() { * Can be used to set the size in bytes that the websocket created by the websocketServlet may be * accept before closing. (Default is -1 - or unlimited) */ + @SuppressWarnings("unused") public void setMaxBinaryMessageSize(Integer maxBinaryMessageSize) { this.maxBinaryMessageSize = maxBinaryMessageSize; } @@ -301,6 +309,7 @@ public Integer getMinVersion() { * Can be used to set the minimum protocol version accepted for the websocketServlet. (Default 13 * - the RFC6455 version) */ + @SuppressWarnings("unused") public void setMinVersion(Integer minVersion) { this.minVersion = minVersion; } @@ -309,6 +318,7 @@ public List getHandlers() { return handlers; } + @SuppressWarnings("unused") public void setHandlers(List handlers) { this.handlers = handlers; } @@ -327,6 +337,7 @@ public String getAllowedOrigins() { } /** The CORS allowed origins. Use * to allow all. */ + @SuppressWarnings("unused") public void setAllowedOrigins(String allowedOrigins) { this.allowedOrigins = allowedOrigins; } @@ -336,6 +347,7 @@ public boolean isCrossOriginFilterOn() { } /** Whether to enable CORS */ + @SuppressWarnings("unused") public void setCrossOriginFilterOn(boolean crossOriginFilterOn) { this.crossOriginFilterOn = crossOriginFilterOn; } @@ -345,6 +357,7 @@ public String getFilterPath() { } /** Context path for filtering CORS */ + @SuppressWarnings("unused") public void setFilterPath(String filterPath) { this.filterPath = filterPath; } @@ -354,6 +367,7 @@ public String getResourceUri() { } /** Name of the websocket channel to use */ + @SuppressWarnings("unused") public void setResourceUri(String resourceUri) { this.resourceUri = resourceUri; } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketFactory.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketFactory.java index 7436e82d4..ea80ce03b 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketFactory.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketFactory.java @@ -29,5 +29,5 @@ DefaultWebsocket newInstance( String protocol, String pathSpec, NodeSynchronization sync, - WebsocketConsumer consumer); + WebSocketConsumer consumer); } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducer.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducer.java similarity index 77% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducer.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducer.java index 29aa0cb26..a9dbf77f3 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducer.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducer.java @@ -19,21 +19,21 @@ */ package de.fhg.aisec.ids.camel.ids.server; +import de.fhg.aisec.ids.camel.ids.WebSocketConstants; import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.support.DefaultProducer; -import org.asynchttpclient.netty.handler.StreamedResponsePublisher; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -public class WebsocketProducer extends DefaultProducer implements WebsocketProducerConsumer { +public class WebSocketProducer extends DefaultProducer implements WebSocketProducerConsumer { - private WebsocketStore store; - private final WebsocketEndpoint endpoint; + private WebSocketStore store; + private final WebSocketEndpoint endpoint; - public WebsocketProducer(WebsocketEndpoint endpoint) { + public WebSocketProducer(WebSocketEndpoint endpoint) { super(endpoint); this.endpoint = endpoint; } @@ -47,16 +47,15 @@ public void process(Exchange exchange) throws Exception { } // look for connection key and get Websocket - String connectionKey = in.getHeader(WebsocketConstants.CONNECTION_KEY, String.class); + String connectionKey = in.getHeader(WebSocketConstants.CONNECTION_KEY, String.class); if (connectionKey != null) { String pathSpec = ""; if (endpoint.getResourceUri() != null) { - pathSpec = WebsocketComponent.createPathSpec(endpoint.getResourceUri()); + pathSpec = WebSocketComponent.createPathSpec(endpoint.getResourceUri()); } DefaultWebsocket websocket = store.get(connectionKey + pathSpec); log.debug("Sending to connection key {} -> {}", connectionKey, message); Future future = sendMessage(websocket, message); - StreamedResponsePublisher sp; if (future != null) { int timeout = endpoint.getSendTimeout(); future.get(timeout, TimeUnit.MILLISECONDS); @@ -71,7 +70,7 @@ public void process(Exchange exchange) throws Exception { } } - public WebsocketEndpoint getEndpoint() { + public WebSocketEndpoint getEndpoint() { return endpoint; } @@ -103,17 +102,8 @@ Future sendMessage(DefaultWebsocket websocket, Object message) { } // Store is set/unset upon connect/disconnect of the producer - public void setStore(WebsocketStore store) { + public void setStore(WebSocketStore store) { this.store = store; } - /** Called when a sleep is interrupted; allows derived classes to handle this case differently */ - protected void handleSleepInterruptedException(InterruptedException e, Exchange exchange) - throws InterruptedException { - if (log.isDebugEnabled()) { - log.debug("Sleep interrupted, are we stopping? {}", isStopping() || isStopped()); - } - Thread.currentThread().interrupt(); - throw e; - } } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducerConsumer.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducerConsumer.java similarity index 91% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducerConsumer.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducerConsumer.java index 3ab783c63..15aa58445 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketProducerConsumer.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketProducerConsumer.java @@ -19,8 +19,8 @@ */ package de.fhg.aisec.ids.camel.ids.server; -public interface WebsocketProducerConsumer { +public interface WebSocketProducerConsumer { /** Gets the endpoint */ - WebsocketEndpoint getEndpoint(); + WebSocketEndpoint getEndpoint(); } diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketStore.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketStore.java similarity index 95% rename from camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketStore.java rename to camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketStore.java index cfabafb28..db0024d71 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketStore.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebSocketStore.java @@ -19,10 +19,11 @@ */ package de.fhg.aisec.ids.camel.ids.server; -import java.util.Collection; import org.apache.camel.Service; -public interface WebsocketStore extends Service { +import java.util.Collection; + +public interface WebSocketStore extends Service { void add(DefaultWebsocket ws); diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketSendException.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketSendException.java index 30755018e..8bab92f66 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketSendException.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/WebsocketSendException.java @@ -31,6 +31,7 @@ public WebsocketSendException(String message, Exchange exchange) { super(message, exchange); } + @SuppressWarnings("unused") public WebsocketSendException(String message, Exchange exchange, Throwable cause) { super(message, exchange, cause); } diff --git a/camel-ids/src/main/resources/META-INF/services/org/apache/camel/component/idsserver b/camel-ids/src/main/resources/META-INF/services/org/apache/camel/component/idsserver index cb4c1b9f3..695ae6f68 100644 --- a/camel-ids/src/main/resources/META-INF/services/org/apache/camel/component/idsserver +++ b/camel-ids/src/main/resources/META-INF/services/org/apache/camel/component/idsserver @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -class=de.fhg.aisec.ids.camel.ids.server.WebsocketComponent +class=de.fhg.aisec.ids.camel.ids.server.WebSocketComponent From f2a96e293af694c860cc81ac7a6bfed2b6985030 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 9 Apr 2020 21:11:46 +0200 Subject: [PATCH 064/237] Gradle Kotlin DSL script for idscp2 --- idscp2/build.gradle | 44 ----------------------------------- idscp2/build.gradle.kts | 51 +++++++++++++++++++++++++++++++++++++++++ libraryVersions.yaml | 1 + 3 files changed, 52 insertions(+), 44 deletions(-) delete mode 100644 idscp2/build.gradle create mode 100644 idscp2/build.gradle.kts diff --git a/idscp2/build.gradle b/idscp2/build.gradle deleted file mode 100644 index 81df80963..000000000 --- a/idscp2/build.gradle +++ /dev/null @@ -1,44 +0,0 @@ -version = libraryVersions.idscp - -apply plugin: 'com.google.protobuf' -apply plugin: 'idea' - -protobuf { - generatedFilesBaseDir = "$projectDir/generated" - - protoc { - artifact = "com.google.protobuf:protoc:${libraryVersions.protobuf}" - } -} - -clean { - delete protobuf.generatedFilesBaseDir -} - -idea { - module { - // mark as generated sources for IDEA - generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") - } -} - -dependencies { - providedByBundle group: 'com.github.microsoft', name: 'TSS.Java', version: '0.3.0' - - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: libraryVersions.log4j - providedByBundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: libraryVersions.log4j - - providedByBundle group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf - - publishCompile group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken - providedByBundle group: 'org.json', name: 'json', version: '20180813' - providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.6.5' - providedByBundle group: 'com.squareup.okhttp3', name: 'okhttp', version: libraryVersions.okhttp - - testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 - testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito -} diff --git a/idscp2/build.gradle.kts b/idscp2/build.gradle.kts new file mode 100644 index 000000000..f2b4ba5af --- /dev/null +++ b/idscp2/build.gradle.kts @@ -0,0 +1,51 @@ +import com.google.protobuf.gradle.protobuf +import org.gradle.plugins.ide.idea.model.IdeaModel +import org.yaml.snakeyaml.Yaml + +@Suppress("UNCHECKED_CAST") val libraryVersions = + Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + +version = libraryVersions["idscp2"] ?: error("IDSCP2 version not specified") + +apply(plugin = "com.google.protobuf") +apply(plugin = "idea") + +val generatedProtoBaseDir = "${projectDir}/generated" + +protobuf { + generatedFilesBaseDir = generatedProtoBaseDir +} + +tasks.named("clean") { + doLast { + delete(generatedProtoBaseDir) + } +} + +configure { + module { + // mark as generated sources for IDEA + generatedSourceDirs.add(File("${generatedProtoBaseDir}/main/java")) + } +} + +dependencies { + providedByBundle("com.github.microsoft", "TSS.Java", "0.3.0") + + providedByBundle("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) + providedByBundle("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) + + providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) + + publishCompile("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) + + providedByBundle("io.jsonwebtoken", "jjwt-impl", libraryVersions["jsonwebtoken"]) + providedByBundle("io.jsonwebtoken", "jjwt-jackson", libraryVersions["jsonwebtoken"]) + providedByBundle("io.jsonwebtoken", "jjwt-api", libraryVersions["jsonwebtoken"]) + providedByBundle("org.json", "json", "20180813") + providedByBundle("org.bitbucket.b_c", "jose4j", "0.6.5") + providedByBundle("com.squareup.okhttp3", "okhttp", libraryVersions["okhttp"]) + + testImplementation("junit", "junit", libraryVersions["junit4"]) + testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) +} diff --git a/libraryVersions.yaml b/libraryVersions.yaml index dc30c6a3b..b3887ada6 100644 --- a/libraryVersions.yaml +++ b/libraryVersions.yaml @@ -1,6 +1,7 @@ # Versions for modules that will be released as libraries api: "2.1.0" idscp: "1.1.0" +idscp2: "1.0.0" # basically, the first requirement, all other libraries depend on this version karaf: "4.2.8" From d33855b8a2177afd959375344f0b57020262c608 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 14 Apr 2020 12:21:00 +0200 Subject: [PATCH 065/237] Get all idscp2 dependency versions from YML file --- idscp2/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idscp2/build.gradle.kts b/idscp2/build.gradle.kts index f2b4ba5af..3a0ffbedf 100644 --- a/idscp2/build.gradle.kts +++ b/idscp2/build.gradle.kts @@ -30,7 +30,7 @@ configure { } dependencies { - providedByBundle("com.github.microsoft", "TSS.Java", "0.3.0") + providedByBundle("com.github.microsoft", "TSS.Java", libraryVersions["tssJava"]) providedByBundle("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) providedByBundle("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) @@ -42,8 +42,8 @@ dependencies { providedByBundle("io.jsonwebtoken", "jjwt-impl", libraryVersions["jsonwebtoken"]) providedByBundle("io.jsonwebtoken", "jjwt-jackson", libraryVersions["jsonwebtoken"]) providedByBundle("io.jsonwebtoken", "jjwt-api", libraryVersions["jsonwebtoken"]) - providedByBundle("org.json", "json", "20180813") - providedByBundle("org.bitbucket.b_c", "jose4j", "0.6.5") + providedByBundle("org.json", "json", libraryVersions["orgJson"]) + providedByBundle("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) providedByBundle("com.squareup.okhttp3", "okhttp", libraryVersions["okhttp"]) testImplementation("junit", "junit", libraryVersions["junit4"]) From dc5660b2f0901460585313d66809c6bd694231ca Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 15 Apr 2020 14:28:45 +0200 Subject: [PATCH 066/237] Fixed has..() methods not generated by protoc --- .../rat/TPM2d/TPM2dProver.java | 16 ++++++---------- .../rat/TPM2d/TPM2dVerifier.java | 17 +++++++---------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java index 333eff4f7..0b29f46bc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java @@ -5,17 +5,13 @@ import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; +import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatChallenge; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResult; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dToRemote; import java.io.IOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A TPM2d RatProver Driver implementation that proves its identity to a remote peer using TPM2d @@ -59,7 +55,7 @@ public class TPM2dProver extends RatProverDriver { * */ - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dProverConfig config = new Tpm2dProverConfig.Builder().build(); public TPM2dProver(){ @@ -105,7 +101,7 @@ public void run() { } // check if message is from rat verifier - if (!msg.hasIdscpRatVerifier()) { + if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATVERIFIER)) { //unexpected message if (LOG.isWarnEnabled()) { LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); @@ -189,7 +185,7 @@ public void run() { } // check if message is from rat verifier - if (!msg.hasIdscpRatVerifier()) { + if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATVERIFIER)) { //unexpected message if (LOG.isWarnEnabled()) { LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java index 3ecb83a2e..ddd55441d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java @@ -8,6 +8,11 @@ import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResponse; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import tss.tpm.*; + import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; @@ -21,14 +26,6 @@ import java.util.Base64; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import tss.tpm.TPMS_ATTEST; -import tss.tpm.TPMS_SIGNATURE_RSAPSS; -import tss.tpm.TPMS_SIGNATURE_RSASSA; -import tss.tpm.TPMT_SIGNATURE; -import tss.tpm.TPM_ALG_ID; /** * A TPM2d RatVerifier driver that verifies the remote peer's identity using TPM2d @@ -70,7 +67,7 @@ public class TPM2dVerifier extends RatVerifierDriver { * */ - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dVerifierConfig config = new Tpm2dVerifierConfig.Builder().build(); public TPM2dVerifier(){ @@ -121,7 +118,7 @@ public void run(){ } // check if response is from rat prover - if (!msg.hasIdscpRatProver()) { + if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATPROVER)) { //unexpected message LOG.warn("Unexpected message from FSM: Expected IdscpRatVerifier"); fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); From b68b180136461a9e215a3b24e26250dcd28393a9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 6 May 2020 11:47:33 +0200 Subject: [PATCH 067/237] Gradle build file fixes --- idscp2/build.gradle.kts | 3 --- karaf-assembly/build.gradle | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/idscp2/build.gradle.kts b/idscp2/build.gradle.kts index 3a0ffbedf..249056733 100644 --- a/idscp2/build.gradle.kts +++ b/idscp2/build.gradle.kts @@ -32,9 +32,6 @@ configure { dependencies { providedByBundle("com.github.microsoft", "TSS.Java", libraryVersions["tssJava"]) - providedByBundle("org.apache.logging.log4j", "log4j-core", libraryVersions["log4j"]) - providedByBundle("org.apache.logging.log4j", "log4j-slf4j-impl", libraryVersions["log4j"]) - providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) publishCompile("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) diff --git a/karaf-assembly/build.gradle b/karaf-assembly/build.gradle index 32636fbd6..367ce7969 100644 --- a/karaf-assembly/build.gradle +++ b/karaf-assembly/build.gradle @@ -62,7 +62,7 @@ jar.dependsOn(assembleKaraf) // Wait for all relevant sub projects before executing assembly process rootProject.subprojects.findAll() { - if (it.name.startsWith("ids-") || it.name.startsWith("camel-") + if (it.name.startsWith("ids") || it.name.startsWith("camel-") || it.name.endsWith("-patch") || it.name.endsWith("-wrapper") || it.name == "karaf-features-ids") { assembleKaraf.dependsOn(it.tasks.install) From 83240857c40659383656c0dcc05b64ffc1709990 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Fri, 15 May 2020 10:20:34 +0200 Subject: [PATCH 068/237] Add unique handshake timers for rat prover and rat verifier --- .../idscp_core/finite_state_machine/FSM.java | 57 +++++++++++++++---- .../finite_state_machine/StateClosed.java | 1 + .../StateEstablished.java | 12 ++-- .../StateWaitForDatAndRat.java | 7 +-- .../StateWaitForDatAndRatVerifier.java | 7 --- .../finite_state_machine/StateWaitForRat.java | 18 +++--- .../StateWaitForRatProver.java | 9 ++- .../StateWaitForRatVerifier.java | 6 +- idscp2/src/test/java/DapsDriverTest.java | 9 +++ 9 files changed, 81 insertions(+), 45 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 9ce383215..fe87b2e77 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -101,6 +101,8 @@ enum FSM_STATE { private Timer datTimer; private Timer ratTimer; private Timer handshakeTimer; + private Timer proverHandshakeTimer; + private Timer verifierHandshakeTimer; /* ---------------- end of Timer --------------- */ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, @@ -123,27 +125,48 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, onControlMessage(InternalControlMessage.REPEAT_RAT); }; + Runnable proverTimeoutHandler = () -> { + LOG.debug("RAT_PROVER_HANDSHAKE_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.REPEAT_RAT); + }; + + Runnable verifierTimeoutHandler = () -> { + LOG.debug("RAT_VERIFIER_HANDSHAKE_TIMER_EXPIRED"); + onControlMessage(InternalControlMessage.REPEAT_RAT); + }; + this.handshakeTimer = new Timer(fsmIsBusy, handshakeTimeoutHandler); this.datTimer = new Timer(fsmIsBusy, datTimeoutHandler); this.ratTimer = new Timer(fsmIsBusy, ratTimeoutHandler); + this.proverHandshakeTimer = new Timer(fsmIsBusy, proverTimeoutHandler); + this.verifierHandshakeTimer = new Timer(fsmIsBusy, verifierTimeoutHandler); /* ------------- end timeout routines ------------- */ /* ------------- FSM STATE Initialization -------------*/ states.put(FSM_STATE.STATE_CLOSED, new StateClosed(this, dapsDriver, onMessageBlock, localSupportedRatSuite, localExpectedRatSuite)); + states.put(FSM_STATE.STATE_WAIT_FOR_HELLO, new StateWaitForHello(this, - handshakeTimer, datTimer, dapsDriver, localSupportedRatSuite, localExpectedRatSuite)); - states.put(FSM_STATE.STATE_WAIT_FOR_RAT, new StateWaitForRat(this, handshakeTimer, ratTimer, - ratTimeout, dapsDriver)); - states.put(FSM_STATE.STATE_WAIT_FOR_RAT_PROVER, new StateWaitForRatProver(this, ratTimer, handshakeTimer, - dapsDriver)); - states.put(FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER, new StateWaitForRatVerifier(this, dapsDriver, ratTimer, - handshakeTimer, ratTimeout)); - states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT, new StateWaitForDatAndRat(this, handshakeTimer, - datTimer, dapsDriver)); - states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, new StateWaitForDatAndRatVerifier(this, - handshakeTimer, datTimer, dapsDriver)); - states.put(FSM_STATE.STATE_ESTABLISHED, new StateEstablished(this, dapsDriver, ratTimer, handshakeTimer)); + handshakeTimer, datTimer, dapsDriver, localSupportedRatSuite, localExpectedRatSuite + )); + + states.put(FSM_STATE.STATE_WAIT_FOR_RAT, new StateWaitForRat(this, handshakeTimer, + verifierHandshakeTimer, proverHandshakeTimer, ratTimer, ratTimeout, dapsDriver)); + + states.put(FSM_STATE.STATE_WAIT_FOR_RAT_PROVER, new StateWaitForRatProver(this, + ratTimer, handshakeTimer, proverHandshakeTimer, dapsDriver)); + + states.put(FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER, new StateWaitForRatVerifier(this, + dapsDriver, ratTimer, handshakeTimer, verifierHandshakeTimer, ratTimeout)); + + states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT, new StateWaitForDatAndRat(this, + handshakeTimer, proverHandshakeTimer, datTimer, dapsDriver)); + + states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, + new StateWaitForDatAndRatVerifier(this, handshakeTimer, datTimer, dapsDriver)); + + states.put(FSM_STATE.STATE_ESTABLISHED, new StateEstablished(this, dapsDriver, + ratTimer, handshakeTimer)); //set initial state @@ -507,6 +530,8 @@ boolean restartRatVerifierDriver(){ } else { //safe the thread ID currentRatVerifierId = Long.toString(ratVerifierDriver.getId()); + LOG.debug("Start verifier_handshake timeout"); + this.verifierHandshakeTimer.resetTimeout(5); return true; } } @@ -515,6 +540,7 @@ boolean restartRatVerifierDriver(){ * Terminate the RatVerifierDriver */ void stopRatVerifierDriver(){ + this.verifierHandshakeTimer.cancelTimeout(); if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ ratVerifierDriver.interrupt(); ratVerifierDriver.terminate(); @@ -538,6 +564,8 @@ boolean restartRatProverDriver(){ } else { //safe the thread ID currentRatProverId = Long.toString(ratProverDriver.getId()); + LOG.debug("Start prover_handshake timeout"); + this.proverHandshakeTimer.resetTimeout(5); return true; } } @@ -546,6 +574,7 @@ boolean restartRatProverDriver(){ * Terminate the RatProverDriver */ void stopRatProverDriver(){ + this.proverHandshakeTimer.cancelTimeout(); if (ratProverDriver != null && ratProverDriver.isAlive()){ ratProverDriver.interrupt(); ratProverDriver.terminate(); @@ -565,6 +594,10 @@ void lockFsm(){ this.ratTimer = null; this.handshakeTimer.cancelTimeout(); this.handshakeTimer = null; + this.proverHandshakeTimer.cancelTimeout(); + this.proverHandshakeTimer = null; + this.verifierHandshakeTimer.cancelTimeout(); + this.verifierHandshakeTimer = null; this.stopRatProverDriver(); this.stopRatVerifierDriver(); fsmIsClosed = true; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 5c305c9e6..465054bcb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -55,6 +55,7 @@ public StateClosed(FSM fsm, } runExitCode(onMessageLock); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_HELLO); } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index 004bf3d8a..a0fef5f34 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -67,9 +67,6 @@ public StateEstablished(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); } )); @@ -82,7 +79,11 @@ public StateEstablished(FSM fsm, LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } - return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); + + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); + + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -113,9 +114,6 @@ public StateEstablished(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 59835fde9..1e93f6e61 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -17,14 +17,12 @@ public class StateWaitForDatAndRat extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRat.class); - private final Timer handshakeTimer; - public StateWaitForDatAndRat(FSM fsm, Timer handshakeTimer, + Timer proverHandshakeTimer, Timer datTimer, DapsDriver dapsDriver ){ - this.handshakeTimer = handshakeTimer; /*--------------------------------------------------- * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description @@ -71,6 +69,7 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_PROVER OK"); + proverHandshakeTimer.cancelTimeout(); return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -177,7 +176,5 @@ public StateWaitForDatAndRat(FSM fsm, @Override void runEntryCode(FSM fsm){ LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT"); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index f54e3d128..17ea8b530 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -18,14 +18,11 @@ public class StateWaitForDatAndRatVerifier extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForDatAndRatVerifier.class); - private final Timer handshakeTimer; - public StateWaitForDatAndRatVerifier(FSM fsm, Timer handshakeTimer, Timer datTimer, DapsDriver dapsDriver){ - this.handshakeTimer = handshakeTimer; /*--------------------------------------------------- * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description * --------------------------------------------------- @@ -91,9 +88,6 @@ public StateWaitForDatAndRatVerifier(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); } )); @@ -138,6 +132,5 @@ public StateWaitForDatAndRatVerifier(FSM fsm, void runEntryCode(FSM fsm){ LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index 8f82ca7d3..fe89b9302 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -17,16 +17,14 @@ public class StateWaitForRat extends State { private static final Logger LOG = LoggerFactory.getLogger(StateWaitForRat.class); - private final Timer handshakeTimer; - public StateWaitForRat(FSM fsm, Timer handshakeTimer, + Timer verifierHandshakeTimer, + Timer proverHandshakeTimer, Timer ratTimer, int ratTimerDelay, DapsDriver dapsDriver){ - this.handshakeTimer = handshakeTimer; - /*--------------------------------------------------- * STATE_WAIT_FOR_RAT - Transition Description @@ -66,6 +64,7 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_PROVER OK"); + proverHandshakeTimer.cancelTimeout(); return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); } )); @@ -73,6 +72,7 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_VERIFIER OK"); + verifierHandshakeTimer.cancelTimeout(); ratTimer.resetTimeout(ratTimerDelay); return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); } @@ -134,6 +134,9 @@ public StateWaitForRat(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } + LOG.debug("Start Handshake Timer"); + handshakeTimer.resetTimeout(5); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); @@ -177,9 +180,6 @@ public StateWaitForRat(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); - return this; } )); @@ -200,10 +200,8 @@ public StateWaitForRat(FSM fsm, ); } - @Override + @Override void runEntryCode(FSM fsm){ LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index 6bb5b2a68..b1ec77967 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -19,6 +19,7 @@ public class StateWaitForRatProver extends State { public StateWaitForRatProver(FSM fsm, Timer ratTimer, Timer handshakeTimer, + Timer proverHandshakeTimer, DapsDriver dapsDriver){ @@ -73,6 +74,9 @@ public StateWaitForRatProver(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } + LOG.debug("Start Handshake Timer"); + handshakeTimer.resetTimeout(5); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } )); @@ -80,7 +84,7 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.RAT_PROVER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_PROVER OK"); - handshakeTimer.cancelTimeout(); + proverHandshakeTimer.cancelTimeout(); return fsm.getState(FSM.FSM_STATE.STATE_ESTABLISHED); } )); @@ -148,8 +152,7 @@ public StateWaitForRatProver(FSM fsm, LOG.error("Cannot run Rat prover, close idscp connection"); return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); + return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 9a36e65ae..823b86899 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -20,6 +20,7 @@ public StateWaitForRatVerifier(FSM fsm, DapsDriver dapsDriver, Timer ratTimer, Timer handshakeTimer, + Timer verifierHandshakeTimer, int ratTimeoutDelay) { /*--------------------------------------------------- @@ -72,6 +73,9 @@ public StateWaitForRatVerifier(FSM fsm, return fsm.getState(FSM_STATE.STATE_CLOSED); } + LOG.debug("Start Handshake Timer"); + handshakeTimer.resetTimeout(5); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -79,7 +83,7 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.RAT_VERIFIER_OK.getValue(), new Transition( event -> { LOG.debug("Received RAT_VERIFIER OK"); - handshakeTimer.cancelTimeout(); + verifierHandshakeTimer.cancelTimeout(); LOG.debug("Start RAT Timer"); ratTimer.resetTimeout(ratTimeoutDelay); return fsm.getState(FSM.FSM_STATE.STATE_ESTABLISHED); diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 1e8d17762..e601c6a2a 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -2,6 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.SecurityRequirements; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; @@ -13,6 +14,7 @@ private String getExpiredToken() { } @Test + @Ignore public void testValidToken() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -44,6 +46,7 @@ public void testValidToken() { } @Test + @Ignore public void testInvalidClient() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -64,6 +67,7 @@ public void testInvalidClient() { } @Test + @Ignore public void testInvalidUrlNonSecure() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -84,6 +88,7 @@ public void testInvalidUrlNonSecure() { } @Test + @Ignore public void testInvalidUrl404() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -104,6 +109,7 @@ public void testInvalidUrl404() { } @Test (expected = RuntimeException.class) + @Ignore public void testInvalidPassword1() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -122,6 +128,7 @@ public void testInvalidPassword1() { } @Test (expected = RuntimeException.class) + @Ignore public void testInvalidPassword2() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -140,6 +147,7 @@ public void testInvalidPassword2() { } @Test (expected = RuntimeException.class) + @Ignore public void testInvalidKeyAlias() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -158,6 +166,7 @@ public void testInvalidKeyAlias() { } @Test + @Ignore public void testInvalidAuditLogging() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() From b42afc44a687dbcc8d13f65f92f8b8441bf08066 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Fri, 15 May 2020 11:25:03 +0200 Subject: [PATCH 069/237] Cleanup FSM, RatDriver, User API, IdscpMessage dependencies --- .../rat/TPM2d/TPM2dProver.java | 41 +++++-------------- .../rat/TPM2d/TPM2dVerifier.java | 33 ++++----------- .../rat/dummy/RatProverDummy.java | 15 ++++--- .../rat/dummy/RatVerifierDummy.java | 14 +++---- .../drivers/interfaces/RatProverDriver.java | 4 +- .../drivers/interfaces/RatVerifierDriver.java | 4 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 4 +- .../idscp_core/finite_state_machine/FSM.java | 16 +++++--- .../finite_state_machine/FsmListener.java | 4 +- .../StateWaitForDatAndRat.java | 4 +- .../finite_state_machine/StateWaitForRat.java | 10 ++++- .../StateWaitForRatProver.java | 5 ++- .../StateWaitForRatVerifier.java | 4 +- 13 files changed, 69 insertions(+), 89 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java index 0b29f46bc..33a1aea39 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java @@ -2,9 +2,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +53,7 @@ public class TPM2dProver extends RatProverDriver { * */ - private final BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dProverConfig config = new Tpm2dProverConfig.Builder().build(); public TPM2dProver(){ @@ -77,7 +75,7 @@ public void setConfig(Object config) { } @Override - public void delegate(IdscpMessage message) { + public void delegate(byte[] message) { queue.add(message); if (LOG.isDebugEnabled()) { LOG.debug("Delegated to prover"); @@ -89,31 +87,23 @@ public void run() { //TPM2d Challenge-Response Protocol // wait for RatChallenge from Verifier - IdscpMessage msg; + byte[] msg; try { msg = queue.take(); if (LOG.isDebugEnabled()) { LOG.debug("Prover receives new message"); } } catch (InterruptedException e) { - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - // check if message is from rat verifier - if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATVERIFIER)) { - //unexpected message - if (LOG.isWarnEnabled()) { - LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + if (this.running){ + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } // parse body to expected tpm2d message wrapper Tpm2dMessageWrapper tpm2dMessageWrapper; try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatVerifier().getData()); + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); } catch (InvalidProtocolBufferException e) { LOG.error("Cannot parse IdscpRatVerifier body", e); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); @@ -168,10 +158,7 @@ public void run() { if (LOG.isDebugEnabled()) { LOG.debug("Send rat response to verifier"); } - fsmListener.onRatProverMessage( - InternalControlMessage.RAT_PROVER_MSG, - IdscpMessageFactory.getIdscpRatProverMessage(response) - ); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, response); // wait for result try { @@ -180,23 +167,15 @@ public void run() { LOG.debug("Prover receives new message"); } } catch (InterruptedException e) { - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - // check if message is from rat verifier - if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATVERIFIER)) { - //unexpected message - if (LOG.isWarnEnabled()) { - LOG.warn("Unexpected message from FSM: Expected IdscpRatProver"); + if (this.running) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); return; } // parse body to expected tpm2d message wrapper try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatVerifier().getData()); + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); } catch (InvalidProtocolBufferException e) { LOG.error("Cannot parse IdscpRatVerifier body", e); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java index ddd55441d..b6f0951dc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java @@ -2,10 +2,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.IDSCPv2; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResponse; import org.checkerframework.checker.nullness.qual.NonNull; @@ -67,7 +64,7 @@ public class TPM2dVerifier extends RatVerifierDriver { * */ - private final BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); private Tpm2dVerifierConfig config = new Tpm2dVerifierConfig.Builder().build(); public TPM2dVerifier(){ @@ -85,7 +82,7 @@ public void setConfig(Object config) { } @Override - public void delegate(IDSCPv2.IdscpMessage message) { + public void delegate(byte[] message) { queue.add(message); LOG.debug("Delegated to Verifier"); } @@ -102,33 +99,24 @@ public void run(){ byte[] ratChallenge = TpmMessageFactory.getAttestationChallengeMessage( nonce, config.getExpectedAType(), config.getExpectedAttestationMask()).toByteArray(); - fsmListener.onRatVerifierMessage( - InternalControlMessage.RAT_VERIFIER_MSG, - IdscpMessageFactory.getIdscpRatVerifierMessage(ratChallenge) - ); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratChallenge); // wait for attestation response - IdscpMessage msg; + byte[] msg; try { msg = queue.take(); LOG.debug("Verifier receives new message"); } catch (InterruptedException e) { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - return; - } - - // check if response is from rat prover - if (!msg.getMessageCase().equals(IdscpMessage.MessageCase.IDSCPRATPROVER)) { - //unexpected message - LOG.warn("Unexpected message from FSM: Expected IdscpRatVerifier"); - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + if (this.running) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + } return; } // parse body to expected tpm2d message wrapper Tpm2dMessageWrapper tpm2dMessageWrapper; try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg.getIdscpRatProver().getData()); + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); } catch (InvalidProtocolBufferException e) { LOG.error("Cannot parse IdscpRatProver body", e); fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); @@ -163,10 +151,7 @@ public void run(){ // create and send rat result LOG.debug("Send rat result to remote prover"); byte[] ratResult = TpmMessageFactory.getAttestationResultMessage(result).toByteArray(); - fsmListener.onRatVerifierMessage( - InternalControlMessage.RAT_VERIFIER_MSG, - IdscpMessageFactory.getIdscpRatVerifierMessage(ratResult) - ); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratResult); // notify fsm about result if (result) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 382c6e8ad..51a270b2e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -1,10 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.IDSCPv2; -import de.fhg.aisec.ids.messages.IDSCPv2.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,14 +16,14 @@ public class RatProverDummy extends RatProverDriver { private static final Logger LOG = LoggerFactory.getLogger(RatProverDummy.class); - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private BlockingQueue queue = new LinkedBlockingQueue<>(); public RatProverDummy(){ super(); } @Override - public void delegate(IdscpMessage message) { + public void delegate(byte[] message) { queue.add(message); if (LOG.isDebugEnabled()) { LOG.debug("Delegated to prover"); @@ -40,18 +37,20 @@ public void run() { try { sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, - IdscpMessageFactory.getIdscpRatProverMessage("test".getBytes())); + "test".getBytes()); if (LOG.isDebugEnabled()) { LOG.debug("Prover waits"); } - IDSCPv2.IdscpMessage m = queue.take(); + byte[] m = queue.take(); if (LOG.isDebugEnabled()) { LOG.debug("Prover receives, send something"); } if (--countDown == 0) break; } catch (InterruptedException e) { - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + if (this.running) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + } return; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index c1293130a..6a9a927f2 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -1,9 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.IDSCPv2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,14 +16,14 @@ public class RatVerifierDummy extends RatVerifierDriver { private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDummy.class); - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private BlockingQueue queue = new LinkedBlockingQueue<>(); public RatVerifierDummy(){ super(); } @Override - public void delegate(IDSCPv2.IdscpMessage message) { + public void delegate(byte[] message) { queue.add(message); if (LOG.isDebugEnabled()) { LOG.debug("Delegated to Verifier"); @@ -41,16 +39,18 @@ public void run(){ if (LOG.isDebugEnabled()) { LOG.debug("Verifier waits"); } - IDSCPv2.IdscpMessage m = queue.take(); + byte[] m = queue.take(); if (LOG.isDebugEnabled()) { LOG.debug("Verifier receives, send something"); } fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, - IdscpMessageFactory.getIdscpRatVerifierMessage("test".getBytes())); + "test".getBytes()); if (--countDown == 0) break; } catch (InterruptedException e) { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + if (this.running) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + } return; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index 581d81d65..08e3a707d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -1,7 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,13 +19,14 @@ public abstract class RatProverDriver extends Thread{ /* * Delegate an IDSCPv2 message to the RatProver driver */ - public void delegate(IdscpMessage message){} + public void delegate(byte[] message){} /* * Terminate and cancel the RatProver driver */ public void terminate() { running = false; + this.interrupt(); } public void setListener(FsmListener listener){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 254a97642..362169234 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -1,7 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; -import de.fhg.aisec.ids.messages.IDSCPv2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,13 +19,14 @@ public abstract class RatVerifierDriver extends Thread{ /* * Delegate the IDSCPv2 message to the RatVerifier driver */ - public void delegate(IdscpMessage message){} + public void delegate(byte[] message){} /* * Terminate and cancel the RatVerifier driver */ public void terminate() { running = false; + this.interrupt(); } public void setListener(FsmListener listener){ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java index ad26a3428..50de6e190 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java @@ -43,8 +43,8 @@ public void close() { * Send data to the peer idscp connector */ public void send(byte[] msg) { - LOG.debug("Send idscp message"); - fsm.send(IdscpMessageFactory.getIdscpDataMessage(msg)); + LOG.debug("Send data "); + fsm.send(msg); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index fe87b2e77..ce81be297 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -3,6 +3,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; @@ -275,16 +276,17 @@ private void onControlMessage(InternalControlMessage controlMessage) { * ignored, else the event is provided to the fsm */ @Override - public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + public void onRatProverMessage(InternalControlMessage controlMessage, byte[] ratMessage) { //check for incorrect usage checkForFsmCircles(); //only allow rat prover messages from current thread Event e; - if (idscpMessage == null){ + if (ratMessage == null){ e = new Event(controlMessage); } else { + IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpRatProverMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -312,16 +314,17 @@ public void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessa * ignored, else the event is provided to the fsm */ @Override - public void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { + public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] ratMessage) { //check for incorrect usage checkForFsmCircles(); //only allow rat verifier messages from current thread Event e; - if (idscpMessage == null){ + if (ratMessage == null){ e = new Event(controlMessage); } else { + IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpRatVerifierMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -448,12 +451,13 @@ public void onClose(){ /* * Send idscp message from the User via the secure channel */ - public void send(IdscpMessage msg){ + public void send(byte[] msg){ //send messages from user only when idscp connection is established fsmIsBusy.lock(); try{ if(isConnected()){ - if (!secureChannel.send(msg.toByteArray())) { + IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpDataMessage(msg); + if (!secureChannel.send(idscpMessage.toByteArray())) { LOG.error("Cannot send IDSCP_DATA via secure channel"); onControlMessage(InternalControlMessage.ERROR); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index a72c40f5d..19639b14e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -18,13 +18,13 @@ public interface FsmListener { /* * A method for providing RatProver messages from the RatProverDriver implementation to the FSM */ - void onRatProverMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage); + void onRatProverMessage(InternalControlMessage controlMessage, byte[] ratMessage); /* * A method for providing RatVerifier messages from the RatVerifierDriver implementation to the * FSM */ - void onRatVerifierMessage(InternalControlMessage controlMessage, IdscpMessage idscpMessage); + void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] ratMessage); /* * A method for providing internal errors to the fsm diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 1e93f6e61..98b1df0c0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -149,7 +149,9 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + assert event.getIdscpMessage().hasIdscpRatVerifier(); + fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() + .getData().toByteArray()); return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index fe89b9302..60a87143c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -153,7 +153,10 @@ public StateWaitForRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + assert event.getIdscpMessage().hasIdscpRatVerifier(); + fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() + .getData().toByteArray()); + return this; } )); @@ -161,7 +164,10 @@ public StateWaitForRat(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - fsm.getRatVerifierDriver().delegate(event.getIdscpMessage()); + assert event.getIdscpMessage().hasIdscpRatProver(); + fsm.getRatVerifierDriver().delegate(event.getIdscpMessage().getIdscpRatProver() + .getData().toByteArray()); + return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index b1ec77967..7f9ca5d09 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -160,7 +160,10 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); - fsm.getRatProverDriver().delegate(event.getIdscpMessage()); + assert event.getIdscpMessage().hasIdscpRatVerifier(); + fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() + .getData().toByteArray()); + return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 823b86899..1d11278d7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -141,7 +141,9 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); - fsm.getRatVerifierDriver().delegate(event.getIdscpMessage()); + assert event.getIdscpMessage().hasIdscpRatProver(); + fsm.getRatVerifierDriver().delegate(event.getIdscpMessage().getIdscpRatProver() + .getData().toByteArray()); return this; } )); From 4569147820429fecfe96df2501c0ed8e0ae8df32 Mon Sep 17 00:00:00 2001 From: Leon Beckmann <> Date: Fri, 15 May 2020 11:29:21 +0200 Subject: [PATCH 070/237] Rename IdscpMessageFactory methods --- .../idscp2/idscp_core/IdscpMessageFactory.java | 16 ++++++++-------- .../idscp_core/finite_state_machine/FSM.java | 6 +++--- .../finite_state_machine/StateClosed.java | 2 +- .../finite_state_machine/StateEstablished.java | 8 ++++---- .../StateWaitForDatAndRat.java | 10 +++++----- .../StateWaitForDatAndRatVerifier.java | 8 ++++---- .../finite_state_machine/StateWaitForHello.java | 10 +++++----- .../finite_state_machine/StateWaitForRat.java | 12 ++++++------ .../StateWaitForRatProver.java | 12 ++++++------ .../StateWaitForRatVerifier.java | 10 +++++----- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index ae951d00e..c8af71f1b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -11,7 +11,7 @@ */ public class IdscpMessageFactory { - public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ + public static IdscpMessage createIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ IdscpDat idscpDat = IdscpDat.newBuilder() .setToken(ByteString.copyFrom(dat)) .build(); @@ -28,7 +28,7 @@ public static IdscpMessage getIdscpHelloMessage(byte[] dat, String[] supportedRa .build(); } - public static IdscpMessage getIdscpCloseMessage(String closeMsg, IdscpClose.CloseCause causeCode){ + public static IdscpMessage createIdscpCloseMessage(String closeMsg, IdscpClose.CloseCause causeCode){ IdscpClose idscpClose = IdscpClose.newBuilder() .setCauseCode(causeCode) .setCauseMsg(closeMsg) @@ -39,13 +39,13 @@ public static IdscpMessage getIdscpCloseMessage(String closeMsg, IdscpClose.Clos .build(); } - public static IdscpMessage getIdscpDatExpiredMessage(){ + public static IdscpMessage createIdscpDatExpiredMessage(){ return IdscpMessage.newBuilder() .setIdscpDatExpired(IdscpDatExpired.newBuilder().build()) .build(); } - public static IdscpMessage getIdscpDatMessage(byte[] dat){ + public static IdscpMessage createIdscpDatMessage(byte[] dat){ IdscpDat idscpDat = IdscpDat.newBuilder() .setToken(ByteString.copyFrom(dat)) .build(); @@ -55,7 +55,7 @@ public static IdscpMessage getIdscpDatMessage(byte[] dat){ .build(); } - public static IdscpMessage getIdscpReRatMessage(String cause){ + public static IdscpMessage createIdscpReRatMessage(String cause){ IdscpReRat idscpReRat = IdscpReRat.newBuilder() .setCause(cause) .build(); @@ -65,7 +65,7 @@ public static IdscpMessage getIdscpReRatMessage(String cause){ .build(); } - public static IdscpMessage getIdscpDataMessage(byte[] data){ + public static IdscpMessage createIdscpDataMessage(byte[] data){ IdscpData idscpData = IdscpData.newBuilder() .setData(ByteString.copyFrom(data)) .build(); @@ -75,7 +75,7 @@ public static IdscpMessage getIdscpDataMessage(byte[] data){ .build(); } - public static IdscpMessage getIdscpRatProverMessage(byte[] body){ + public static IdscpMessage createIdscpRatProverMessage(byte[] body){ IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder() .setData(ByteString.copyFrom(body)) .build(); @@ -85,7 +85,7 @@ public static IdscpMessage getIdscpRatProverMessage(byte[] body){ .build(); } - public static IdscpMessage getIdscpRatVerifierMessage(byte[] body){ + public static IdscpMessage createIdscpRatVerifierMessage(byte[] body){ IdscpRatVerifier idscpRatVerifier = IdscpRatVerifier.newBuilder() .setData(ByteString.copyFrom(body)) .build(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index ce81be297..f59131ab4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -286,7 +286,7 @@ public void onRatProverMessage(InternalControlMessage controlMessage, byte[] rat if (ratMessage == null){ e = new Event(controlMessage); } else { - IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpRatProverMessage(ratMessage); + IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpRatProverMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -324,7 +324,7 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] r if (ratMessage == null){ e = new Event(controlMessage); } else { - IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpRatVerifierMessage(ratMessage); + IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpRatVerifierMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -456,7 +456,7 @@ public void send(byte[] msg){ fsmIsBusy.lock(); try{ if(isConnected()){ - IdscpMessage idscpMessage = IdscpMessageFactory.getIdscpDataMessage(msg); + IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpDataMessage(msg); if (!secureChannel.send(idscpMessage.toByteArray())) { LOG.error("Cannot send IDSCP_DATA via secure channel"); onControlMessage(InternalControlMessage.ERROR); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 465054bcb..36a2ce507 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -45,7 +45,7 @@ public StateClosed(FSM fsm, LOG.debug("Send IDSCP_HELLO"); IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. - getIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); + createIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); if (!fsm.sendFromFSM(idscpHello)) { LOG.error("Cannot send IdscpHello. Close connection"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index a0fef5f34..e08732944 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -46,7 +46,7 @@ public StateEstablished(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -57,7 +57,7 @@ public StateEstablished(FSM fsm, LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); ratTimer.cancelTimeout(); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage(""))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpReRatMessage(""))) { LOG.error("Cannot send ReRat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -75,7 +75,7 @@ public StateEstablished(FSM fsm, event -> { ratTimer.cancelTimeout(); LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -104,7 +104,7 @@ public StateEstablished(FSM fsm, event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send Dat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 98b1df0c0..029bce545 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -44,7 +44,7 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -60,7 +60,7 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -78,7 +78,7 @@ public StateWaitForDatAndRat(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -111,7 +111,7 @@ public StateWaitForDatAndRat(FSM fsm, long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage( + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage( "No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -132,7 +132,7 @@ public StateWaitForDatAndRat(FSM fsm, event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send Dat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 17ea8b530..26aa49d24 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -39,7 +39,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -55,7 +55,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -77,7 +77,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } LOG.debug("Remote DAT is valid. Set dat timeout"); @@ -96,7 +96,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index 7f9915325..9ef0669b0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -53,7 +53,7 @@ public StateWaitForHello(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Received stop signal from user. Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -62,7 +62,7 @@ public StateWaitForHello(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake Timeout", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake Timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -87,7 +87,7 @@ public StateWaitForHello(FSM fsm, idscpHello.getExpectedRatSuiteList().toArray()); if (proverMechanism == null){ LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Prover mechanism", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No match for RAT Prover mechanism", IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -96,7 +96,7 @@ public StateWaitForHello(FSM fsm, idscpHello.getSupportedRatSuiteList().toArray()); if (verifierMechanism == null){ LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No match for RAT Verifier mechanism", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No match for RAT Verifier mechanism", IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -108,7 +108,7 @@ public StateWaitForHello(FSM fsm, if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("No valid DAT", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index 60a87143c..a8d4be723 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -55,7 +55,7 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -82,7 +82,7 @@ public StateWaitForRat(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -92,7 +92,7 @@ public StateWaitForRat(FSM fsm, event -> { LOG.error("RAT_VERIFIER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_VERIFIER failed", IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -129,7 +129,7 @@ public StateWaitForRat(FSM fsm, LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -144,7 +144,7 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -176,7 +176,7 @@ public StateWaitForRat(FSM fsm, event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index 7f9ca5d09..4ca9a9443 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -43,7 +43,7 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -58,7 +58,7 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -69,7 +69,7 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); ratTimer.cancelTimeout(); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -93,7 +93,7 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_PROVER failed", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -116,7 +116,7 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpReRatMessage(""))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpReRatMessage(""))) { LOG.error("Cannot send ReRat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -143,7 +143,7 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 1d11278d7..0210b1c7d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -42,7 +42,7 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("User close", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -58,7 +58,7 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -68,7 +68,7 @@ public StateWaitForRatVerifier(FSM fsm, LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -94,7 +94,7 @@ public StateWaitForRatVerifier(FSM fsm, event -> { LOG.error("RAT_VERIFIER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.getIdscpCloseMessage("RAT_VERIFIER failed", + fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_VERIFIER failed", IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -124,7 +124,7 @@ public StateWaitForRatVerifier(FSM fsm, event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.getIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } From c9b6690c8bffc9393fee2fe0a70b3f0df52a4c38 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Sun, 17 May 2020 12:36:23 +0200 Subject: [PATCH 071/237] Introduced message types and new handler interfaces/classes --- .../aisec/ids/idscp2/IDSCPv2Initiator.java | 9 +- .../secure_channel/NativeTLSDriver.java | 7 +- .../secure_channel/server/TLSServer.java | 12 +- .../server/TLSServerThread.java | 6 +- .../interfaces/SecureChannelDriver.java | 4 +- .../idscp2/idscp_core/IDSCPv2Connection.java | 74 ---------- .../idscp2/idscp_core/Idscp2Connection.java | 134 ++++++++++++++++++ .../idscp_core/IdscpConnectionListener.java | 12 ++ .../idscp_core/IdscpMessageFactory.java | 21 ++- .../idscp_core/IdscpMessageListener.java | 12 ++ .../idscp2/idscp_core/IdscpMsgListener.java | 17 --- .../configuration/IDSCPv2Callback.java | 4 +- .../configuration/IDSCPv2Configuration.java | 36 ++--- .../idscp_core/finite_state_machine/FSM.java | 77 +++++----- .../finite_state_machine/StateClosed.java | 2 +- .../StateEstablished.java | 3 +- .../idscp_server/IDSCPv2Server.java | 31 ++-- ...Listener.java => IdscpServerListener.java} | 8 +- idscp2/src/main/proto/idscpv2.proto | 34 +++-- .../src/test/java/IDSCPv2ClientInitiator.java | 38 +++-- .../src/test/java/IDSCPv2ServerInitiator.java | 36 +++-- 21 files changed, 342 insertions(+), 235 deletions(-) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/{IdscpConnectionListener.java => IdscpServerListener.java} (65%) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java index 7ff21c26d..076d58289 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java @@ -1,6 +1,6 @@ package de.fhg.aisec.ids.idscp2; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; /** * An interface for the IDSCPv2Initiator class, that implements callback functions that notifies @@ -13,15 +13,10 @@ public interface IDSCPv2Initiator { /* * Called when a new connection is established */ - void newConnectionHandler(IDSCPv2Connection connection); + void newConnectionHandler(Idscp2Connection connection); /* * Called when an error occurred in the underlying IDSCPv2 protocol */ void errorHandler(String error); - - /* - * Called when a connection with the given connectionID was closed - */ - void connectionClosedHandler(String connectionId); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index f36547a3d..8368c96d9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -6,7 +6,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,15 +47,14 @@ public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { */ @Override public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, - IdscpConnectionListener idscpServerCallback) { + IdscpServerListener idscpServerCallback) { try { TLSServer tlsServer = new TLSServer(settings, configCallback, idscpServerCallback); tlsServer.start(); return tlsServer; } catch (IOException | NoSuchAlgorithmException | KeyManagementException e){ - LOG.error("listen() failed. {}", e.getMessage()); - LOG.debug(Arrays.toString(e.getStackTrace())); + LOG.error("listen() failed.", e); } return null; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index e1171a82f..63f5ecdd9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -5,7 +5,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,12 +26,12 @@ public class TLSServer extends Thread implements SecureServer { private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); private volatile boolean isRunning = false; - private ServerSocket serverSocket; - private IDSCPv2Callback idscpConfigCallback; //no race conditions - private IdscpConnectionListener idscpServerCallback; + private final ServerSocket serverSocket; + private final IDSCPv2Callback idscpConfigCallback; //no race conditions + private final IdscpServerListener idscpServerCallback; public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, - IdscpConnectionListener idscpServerCallback) + IdscpServerListener idscpServerCallback) throws IOException, NoSuchAlgorithmException, KeyManagementException { this.idscpConfigCallback = configCallback; this.idscpServerCallback = idscpServerCallback; @@ -115,7 +115,7 @@ public void run(){ server.start(); } - if (serverSocket != null && !serverSocket.isClosed()){ + if (!serverSocket.isClosed()){ try { serverSocket.close(); } catch (IOException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index c2c3ddf9e..3ed6c0ff5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -2,7 +2,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsSessionVerificationHelper; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -34,12 +34,12 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListene private DataOutputStream out; private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch private IDSCPv2Callback configCallback; //no race conditions - private IdscpConnectionListener idscpServerCallback; //no race conditions + private IdscpServerListener idscpServerCallback; //no race conditions private CountDownLatch listenerLatch = new CountDownLatch(1); private CountDownLatch tlsVerificationLatch = new CountDownLatch(1); - TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback configCallback, IdscpConnectionListener idscpServerCallback){ + TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback configCallback, IdscpServerListener idscpServerCallback){ this.sslSocket = sslSocket; this.configCallback = configCallback; this.idscpServerCallback = idscpServerCallback; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 2ea75dcd4..3adab7967 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -2,7 +2,7 @@ import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; /** * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function @@ -21,5 +21,5 @@ public interface SecureChannelDriver { * Starting a secure server */ SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, - IdscpConnectionListener idscpServerCallback); + IdscpServerListener idscpServerCallback); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java deleted file mode 100644 index 50de6e190..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IDSCPv2Connection.java +++ /dev/null @@ -1,74 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core; - -import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Arrays; - -/** - * The IDSCPv2 Connection class holds connections between connectors - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class IDSCPv2Connection implements IdscpMsgListener { - private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Connection.class); - - private FSM fsm; - private String connectionId; - private IDSCPv2Initiator user; - private IdscpConnectionListener server; - - public IDSCPv2Connection(FSM fsm, String connectionId, IDSCPv2Initiator user, IdscpConnectionListener server){ - this.fsm = fsm; - this.connectionId = connectionId; - this.user = user; - this.server = server; - } - - /* - * Close the idscp connection - */ - public void close() { - // unregister connection from the idscp server - if (server != null) { - server.connectionClosedHandler(connectionId); - } - fsm.terminate(); - } - - /* - * Send data to the peer idscp connector - */ - public void send(byte[] msg) { - LOG.debug("Send data "); - fsm.send(msg); - } - - @Override - public void onMessage(byte[] msg) { - LOG.info("Received new IDSCP Message: " + Arrays.toString(msg)); - } - - @Override - public void onClose() { - LOG.debug("Connection with id {} has been closed, notify user", connectionId); - user.connectionClosedHandler(connectionId); - if (server != null) { - server.connectionClosedHandler(connectionId); - } - } - - /* - * Check if the idscp connection is currently established - */ - public boolean isConnected() { - return fsm.isConnected(); - } - - public String getConnectionId() { - return connectionId; - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java new file mode 100644 index 000000000..0419168b1 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -0,0 +1,134 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +/** + * The IDSCPv2 Connection class holds connections between connectors + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + * @author Michael Lux (michael.lux@aisec.fraunhofer.de) + */ +public class Idscp2Connection { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2Connection.class); + + private final FSM fsm; + private final String connectionId; + private final Set connectionListeners = new HashSet<>(); + private final Set genericMessageListeners = new HashSet<>(); + private final Map> messageListeners = new HashMap<>(); + + public Idscp2Connection(FSM fsm, String connectionId) { + this.fsm = fsm; + this.connectionId = connectionId; + } + + /* + * Close the idscp connection + */ + public void close() { + // unregister connection from the idscp server + synchronized (connectionListeners) { + connectionListeners.forEach(l -> l.onClose(connectionId)); + } + fsm.terminate(); + } + + /* + * Send data to the peer idscp connector + */ + public void send(String type, byte[] msg) { + LOG.debug("Send data of type \"" + type + "\" "); + fsm.send(type, msg); + } + + public void onMessage(String type, byte[] msg) { + LOG.debug("Received new IDSCP Message: " + Arrays.toString(msg)); + synchronized (genericMessageListeners) { + genericMessageListeners.forEach(l -> l.onMessage(type, msg)); + } + Set listeners = messageListeners.get(type); + if (listeners != null) { + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (listeners) { + listeners.forEach(l -> l.onMessage(type, msg)); + } + } + } + + public void onClose() { + LOG.debug("Connection with id {} has been closed, notify user", connectionId); + synchronized (connectionListeners) { + connectionListeners.forEach(l -> l.onClose(connectionId)); + } + } + + /* + * Check if the idscp connection is currently established + */ + public boolean isConnected() { + return fsm.isConnected(); + } + + public String getConnectionId() { + return connectionId; + } + + public void addConnectionListener(IdscpConnectionListener listener) { + synchronized (connectionListeners) { + connectionListeners.add(listener); + } + } + + public boolean removeConnectionListener(IdscpConnectionListener listener) { + synchronized (connectionListeners) { + return connectionListeners.remove(listener); + } + } + + public void addGenericMessageListener(IdscpMessageListener listener) { + synchronized (genericMessageListeners) { + genericMessageListeners.add(listener); + } + } + + public boolean removeGenericMessageListener(IdscpMessageListener listener) { + synchronized (genericMessageListeners) { + return genericMessageListeners.remove(listener); + } + } + + public void addMessageListener(@Nullable String type, IdscpMessageListener listener) { + synchronized (messageListeners) { + Set messageTypeListeners + = messageListeners.computeIfAbsent(type, k -> new HashSet<>()); + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (messageTypeListeners) { + messageTypeListeners.add(listener); + } + messageListeners.put(type, messageTypeListeners); + } + } + + public boolean removeMessageListener(@Nullable String type, IdscpMessageListener listener) { + synchronized (messageListeners) { + Set messageTypeListeners = messageListeners.get(type); + if (messageTypeListeners == null) { + return false; + } + final boolean ret; + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (messageTypeListeners) { + ret = messageTypeListeners.remove(listener); + } + if (messageTypeListeners.isEmpty()) { + messageListeners.remove(type); + } + return ret; + } + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java new file mode 100644 index 000000000..bd5d4b6f0 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +/** + * An IDSCP Connection Listener interface that is implemented by the IDSCPv2 Server to notify the + * server about lifetimes of IDSCP connections. The server caches all active connections. + */ +public interface IdscpConnectionListener { + + void onError(String error); + + void onClose(String connectionId); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java index c8af71f1b..262040c66 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java @@ -65,16 +65,29 @@ public static IdscpMessage createIdscpReRatMessage(String cause){ .build(); } - public static IdscpMessage createIdscpDataMessage(byte[] data){ - IdscpData idscpData = IdscpData.newBuilder() - .setData(ByteString.copyFrom(data)) - .build(); + public static IdscpMessage createIdscpDataMessage(String type, Integer typeTag, byte[] data) { + IdscpData.Builder idscpData = IdscpData.newBuilder() + .setData(ByteString.copyFrom(data)); + if (type != null) { + idscpData.setType(type); + } + if (typeTag != null) { + idscpData.setTypeTag(typeTag); + } return IdscpMessage.newBuilder() .setIdscpData(idscpData) .build(); } + public static IdscpMessage createIdscpDataMessage(int shortType, byte[] data) { + return createIdscpDataMessage(null, shortType, data); + } + + public static IdscpMessage createIdscpDataMessage(String type, byte[] data) { + return createIdscpDataMessage(type, null, data); + } + public static IdscpMessage createIdscpRatProverMessage(byte[] body){ IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder() .setData(ByteString.copyFrom(body)) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java new file mode 100644 index 000000000..5c3d3d39d --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +/** + * An interface for an IDSCP message listener + */ +public interface IdscpMessageListener { + + /* + * notify the listener about new data + */ + void onMessage(String type, byte[] data); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java deleted file mode 100644 index 37ed40008..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMsgListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core; - -/** - * An interface for an IDSCP message listener - */ -public interface IdscpMsgListener { - - /* - * notify the listener about new data via idscp - */ - void onMessage(byte[] data); - - /* - * notify the listener that the idscp connection was closed - */ - void onClose(); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java index 91bc2923b..9c1fd0ba5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java @@ -1,6 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; /** @@ -21,7 +21,7 @@ public interface IDSCPv2Callback { */ void secureChannelListenHandler( SecureChannel secureChannel, - IdscpConnectionListener idscpServer + IdscpServerListener idscpServer ); } \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java index d9b06300f..0c4754fe9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java @@ -3,10 +3,10 @@ import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,12 +20,12 @@ public class IDSCPv2Configuration implements IDSCPv2Callback { private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Configuration.class); - private IDSCPv2Initiator user; - private DapsDriver dapsDriver; - private SecureChannelDriver secureChannelDriver; + private final IDSCPv2Initiator user; + private final DapsDriver dapsDriver; + private final SecureChannelDriver secureChannelDriver; private final String[] localExpectedRatCipher; private final String[] localSupportedRatCipher; - private int ratTimeout; + private final int ratTimeout; public IDSCPv2Configuration(IDSCPv2Initiator initiator, @@ -58,8 +58,8 @@ public void connect(IDSCPv2Settings settings){ public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { LOG.info("Starting new IDSCPv2 server at port {}", settings.getServerPort()); - SecureServer secureServer; - IDSCPv2Server idscpServer = new IDSCPv2Server(); + final SecureServer secureServer; + final IDSCPv2Server idscpServer = new IDSCPv2Server(); if ((secureServer = secureChannelDriver.listen(settings, this, idscpServer)) == null){ throw new IDSCPv2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); @@ -76,7 +76,7 @@ public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { * to the user * * If the secure channel was established, a new FSM is created for this connection and the - * IDSCPv2 handshake is started. After a successful handshake, a new IDSCPv2Connection is + * IDSCPv2 handshake is started. After a successful handshake, a new Idscp2Connection is * created and provided to the user */ @Override @@ -96,8 +96,8 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { } String connectionId = UUID.randomUUID().toString(); - IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId, user, null); - fsm.registerMessageListener(newConnection); + Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); + fsm.registerConnection(newConnection); LOG.info("A new IDSCPv2 connection with id {} was created", connectionId); user.newConnectionHandler(newConnection); } @@ -110,11 +110,11 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { * ignored * * If the secure channel was established, a new FSM is created for this connection and the - * IDSCPv2 handshake is started. After a successful handshake, a new IDSCPv2Connection is + * IDSCPv2 handshake is started. After a successful handshake, a new Idscp2Connection is * created and provided to the user and the IDSCPv2 server */ @Override - public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnectionListener idscpServer) { + public void secureChannelListenHandler(SecureChannel secureChannel, IdscpServerListener idscpServer) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, @@ -126,15 +126,15 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpConnect return; } - //create new IDSCPv2Connection + //create new Idscp2Connection String connectionId = UUID.randomUUID().toString(); - IDSCPv2Connection newConnection = new IDSCPv2Connection(fsm, connectionId, user, idscpServer); - fsm.registerMessageListener(newConnection); + Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); + fsm.registerConnection(newConnection); LOG.info("A new idscpv2 connection with id {} was created", connectionId); - idscpServer.newConnectionHandler(newConnection); //bind connection to idscp server + idscpServer.onConnect(newConnection); //bind connection to idscp server user.newConnectionHandler(newConnection); } else { - LOG.warn("An incoming idscpv2 client connection request failed because no secure channel was established"); + LOG.warn("An incoming idscpv2 client connection request failed because the secure channel is null."); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index f59131ab4..72c9abb3b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -3,8 +3,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMsgListener; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; @@ -31,7 +31,7 @@ public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); /* ----------- IDSCPv2 Protocol States ---------- */ - private HashMap states = new HashMap<>(); + private final HashMap states = new HashMap<>(); enum FSM_STATE { STATE_CLOSED, @@ -47,7 +47,7 @@ enum FSM_STATE { private State currentState; /* ---------------- end of states --------------- */ - private SecureChannel secureChannel; //secure underlying channel + private final SecureChannel secureChannel; //secure underlying channel private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; @@ -72,8 +72,8 @@ enum FSM_STATE { * And a listener latch to ensure that the listener is available and the message does not get * lost */ - private IdscpMsgListener listener = null; - private final CountDownLatch listenerLatch = new CountDownLatch(1); + private Idscp2Connection connection; + private final CountDownLatch connectionLatch = new CountDownLatch(1); /* * A FIFO-fair synchronization lock for the finite state machine @@ -99,11 +99,11 @@ enum FSM_STATE { private boolean fsmIsClosed = false; /* ---------------------- Timer ---------------------- */ - private Timer datTimer; - private Timer ratTimer; - private Timer handshakeTimer; - private Timer proverHandshakeTimer; - private Timer verifierHandshakeTimer; + private final Timer datTimer; + private final Timer ratTimer; + private final Timer handshakeTimer; + private final Timer proverHandshakeTimer; + private final Timer verifierHandshakeTimer; /* ---------------- end of Timer --------------- */ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, @@ -451,18 +451,18 @@ public void onClose(){ /* * Send idscp message from the User via the secure channel */ - public void send(byte[] msg){ + public void send(String type, byte[] msg){ //send messages from user only when idscp connection is established fsmIsBusy.lock(); try{ if(isConnected()){ - IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpDataMessage(msg); + IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpDataMessage(type, msg); if (!secureChannel.send(idscpMessage.toByteArray())) { LOG.error("Cannot send IDSCP_DATA via secure channel"); onControlMessage(InternalControlMessage.ERROR); } } else { - LOG.error("Cannot send IDSCP_DATA because protocol is not established"); + LOG.error("Cannot send IDSCP_DATA because connection is not established"); } } finally { fsmIsBusy.unlock(); @@ -479,9 +479,9 @@ public boolean isConnected(){ /* * Register an IDSCPv2 message listener */ - public void registerMessageListener(IdscpMsgListener listener){ - this.listener = listener; - listenerLatch.countDown(); + public void registerConnection(Idscp2Connection connection){ + this.connection = connection; + connectionLatch.countDown(); } /* @@ -543,8 +543,8 @@ boolean restartRatVerifierDriver(){ /* * Terminate the RatVerifierDriver */ - void stopRatVerifierDriver(){ - this.verifierHandshakeTimer.cancelTimeout(); + void stopRatVerifierDriver() { + verifierHandshakeTimer.cancelTimeout(); if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ ratVerifierDriver.interrupt(); ratVerifierDriver.terminate(); @@ -578,7 +578,7 @@ boolean restartRatProverDriver(){ * Terminate the RatProverDriver */ void stopRatProverDriver(){ - this.proverHandshakeTimer.cancelTimeout(); + proverHandshakeTimer.cancelTimeout(); if (ratProverDriver != null && ratProverDriver.isAlive()){ ratProverDriver.interrupt(); ratProverDriver.terminate(); @@ -589,29 +589,22 @@ void stopRatProverDriver(){ * Lock the fsm forever, terminate the timers and drivers, close the secure channel * and notify User or handshake lock about closure */ - void lockFsm(){ - try { - secureChannel.close(); - this.datTimer.cancelTimeout(); - this.datTimer = null; - this.ratTimer.cancelTimeout(); - this.ratTimer = null; - this.handshakeTimer.cancelTimeout(); - this.handshakeTimer = null; - this.proverHandshakeTimer.cancelTimeout(); - this.proverHandshakeTimer = null; - this.verifierHandshakeTimer.cancelTimeout(); - this.verifierHandshakeTimer = null; - this.stopRatProverDriver(); - this.stopRatVerifierDriver(); - fsmIsClosed = true; - } catch (NullPointerException ignored){} + void shutdownFsm() { + secureChannel.close(); + datTimer.cancelTimeout(); + ratTimer.cancelTimeout(); + handshakeTimer.cancelTimeout(); + // Cancels proverHandshakeTimer + this.stopRatProverDriver(); + // Cancels verifierHandshakeTimer + this.stopRatVerifierDriver(); + fsmIsClosed = true; //notify upper layer via handshake or closeListener try { - if (handshakeResultAvailable){ - listenerLatch.await(); - listener.onClose(); + if (handshakeResultAvailable) { + connectionLatch.await(); + connection.onClose(); } else { notifyHandshakeCompleteLock(); } @@ -623,10 +616,10 @@ void lockFsm(){ /* * Provide IDSCPv2 message to the message listener */ - void notifyIdscpMsgListener(byte[] data) { + void notifyIdscpMsgListener(String type, byte[] data) { try { - this.listenerLatch.await(); - this.listener.onMessage(data); + this.connectionLatch.await(); + this.connection.onMessage(type, data); LOG.debug("Idscp data were passed to connection listener"); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 36a2ce507..919ca4aaa 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -80,7 +80,7 @@ void runEntryCode(FSM fsm){ //State Closed entry code LOG.debug("Switched to state STATE_CLOSED"); LOG.debug("Terminate and free all resources and lock fsm forever"); - fsm.lockFsm(); + fsm.shutdownFsm(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index e08732944..055e9cd09 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -120,7 +120,8 @@ public StateEstablished(FSM fsm, this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( event -> { - fsm.notifyIdscpMsgListener(event.getIdscpMessage().getIdscpData().toByteArray()); + IDSCPv2.IdscpData data = event.getIdscpMessage().getIdscpData(); + fsm.notifyIdscpMsgListener(data.getType(), data.getData().toByteArray()); return this; } )); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java index d807b90b6..049df87ab 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java @@ -1,11 +1,13 @@ package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; @@ -16,19 +18,14 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IDSCPv2Server implements IdscpConnectionListener{ +public class IDSCPv2Server implements IdscpServerListener { private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); private SecureServer secureServer; //no race conditions using CountDownLatch - private CountDownLatch secureServerLatch = new CountDownLatch(1); - private ConcurrentHashMap connections = new ConcurrentHashMap<>(); + private final CountDownLatch secureServerLatch = new CountDownLatch(1); + private final ConcurrentHashMap connections = new ConcurrentHashMap<>(); - public IDSCPv2Server(){} - - public IDSCPv2Server(SecureServer secureServer){ - this.secureServer = secureServer; - secureServerLatch.countDown(); - } + public IDSCPv2Server() {} /* * Terminate the IDSCPv2 server, the secure server and close all connections @@ -48,7 +45,7 @@ public void terminate(){ * Close all open IDSCPv2 connections of this server */ public void terminateAllSessions(){ - for (IDSCPv2Connection c : connections.values()){ + for (Idscp2Connection c : connections.values()){ c.close(); LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); connections.remove(c.getConnectionId()); @@ -69,29 +66,29 @@ public boolean isRunning(){ } /* - * Get a IDSCPv2Connection from the server cache by the connectionID + * Get a Idscp2Connection from the server cache by the connectionID * * return null if no connection was found with this ID */ - public IDSCPv2Connection getConnectionById(String connectionId){ + public Idscp2Connection getConnectionById(String connectionId){ return connections.get(connectionId); } /* * return a list of all open IDSCPv2 connections of this server */ - public List getAllConnections(){ - return new ArrayList<>(connections.values()); + public Collection getAllConnections(){ + return Collections.unmodifiableCollection(connections.values()); } @Override - public void newConnectionHandler(IDSCPv2Connection connection) { + public void onConnect(Idscp2Connection connection) { LOG.debug("Binding new idscpv2 connection to server {}", this.toString()); connections.put(connection.getConnectionId(), connection); } @Override - public void connectionClosedHandler(String connectionId) { + public void onClose(String connectionId) { LOG.debug("Removing connection with id {} from server storage", connectionId); connections.remove(connectionId); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java similarity index 65% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java index 13911c906..d0600a977 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpConnectionListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java @@ -1,20 +1,20 @@ package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; /** * An IDSCP Connection Listener interface that is implemented by the IDSCPv2 Server to notify the * server about lifetimes of IDSCP connections. The server caches all active connections. */ -public interface IdscpConnectionListener { +public interface IdscpServerListener { /* * Notify the server that a new connection was established */ - void newConnectionHandler(IDSCPv2Connection connection); + void onConnect(Idscp2Connection connection); /* * Notify the server that connection has been closed */ - void connectionClosedHandler(String connectionId); + void onClose(String connectionId); } diff --git a/idscp2/src/main/proto/idscpv2.proto b/idscp2/src/main/proto/idscpv2.proto index 658d2e6c8..0ca28a5c7 100644 --- a/idscp2/src/main/proto/idscpv2.proto +++ b/idscp2/src/main/proto/idscpv2.proto @@ -17,12 +17,21 @@ message IdscpMessage { } } -//IDSCP messages +// IDSCP messages + message IdscpHello { - int32 version = 1; //IDSCP protocol version - IdscpDat dynamicAttributeToken = 2; //initial dynamicAttributeToken - repeated string supportedRatSuite = 3; //RemoteAttestationCipher prover - repeated string expectedRatSuite = 4; //RemoteAttestationCipher verifier + // IDSCP protocol version + int32 version = 1; + // Initial dynamic attribute token (DAT) + IdscpDat dynamicAttributeToken = 2; + // Set of supported remote attestation (RAT) methods (prover role) + repeated string supportedRatSuite = 3; + // Set of accepted RAT methods (verifier role) + repeated string expectedRatSuite = 4; + // Maximum number of supported message type cache entries + int32 maxCacheEntries = 5; + // Maximum supported total length of type cache entries in UTF-8 + int32 maxTotalCacheSize = 6; } message IdscpClose { @@ -42,15 +51,17 @@ message IdscpClose { string cause_msg = 2; } -message IdscpDatExpired { //request new dynamicAttributeToken +// For requesting new DAT +message IdscpDatExpired { } message IdscpDat { bytes token = 1; } -message IdscpReRat { //request new remoteAttestatio - string cause = 1; //optional +// For requesting new RAT +message IdscpReRat { + string cause = 1; } message IdscpRatProver { @@ -62,5 +73,10 @@ message IdscpRatVerifier { } message IdscpData { - bytes data = 1 ; + // Payload + bytes data = 1; + // Message type (e.g. MIME type) as string + string type = 2; + // Integer for cached types or type caching + int32 typeTag = 3; } \ No newline at end of file diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/test/java/IDSCPv2ClientInitiator.java index 8e49a7a44..06ab74b40 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ClientInitiator.java @@ -10,18 +10,17 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; -import java.util.concurrent.ConcurrentHashMap; +import java.nio.charset.StandardCharsets; public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { - private ConcurrentHashMap connections = new ConcurrentHashMap<>(); - public void init(IDSCPv2Settings settings){ SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = @@ -63,19 +62,30 @@ public void init(IDSCPv2Settings settings){ } @Override - public void newConnectionHandler(IDSCPv2Connection connection) { - this.connections.put(connection.getConnectionId(), connection); - System.out.println("User: New connection with id " + connection.getConnectionId()); - } + public void newConnectionHandler(Idscp2Connection connection) { + System.out.println("Client: New connection with id " + connection.getConnectionId()); + connection.addConnectionListener(new IdscpConnectionListener() { + @Override + public void onError(String error) { + System.out.println("Client error occurred: " + error); + } - @Override - public void errorHandler(String error) { - System.out.println("User: Error occurred: " + error); + @Override + public void onClose(String connectionId) { + System.out.println("Client: Connection with id " + connectionId + " has been closed"); + } + }); + connection.addGenericMessageListener(((type, data) -> System.out.println( + "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); + // Register listener for server reply + connection.addMessageListener("pong", (type, data) -> + System.out.println("Received pong message: " + new String(data, StandardCharsets.UTF_8))); + System.out.println("Sending PING..."); + connection.send("ping", "PING".getBytes(StandardCharsets.UTF_8)); } @Override - public void connectionClosedHandler(String connectionId) { - System.out.println("User: Connection closed"); - connections.remove(connectionId); + public void errorHandler(String error) { + System.out.println("Client error occurred: " + error); } } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/test/java/IDSCPv2ServerInitiator.java index 9c1a9802b..3b62e7961 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/test/java/IDSCPv2ServerInitiator.java @@ -11,17 +11,20 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.IDSCPv2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.IdscpConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; +import java.nio.charset.StandardCharsets; + public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { - //private ConcurrentHashMap connections = new ConcurrentHashMap<>(); + //private ConcurrentHashMap connections = new ConcurrentHashMap<>(); public void init(IDSCPv2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); @@ -77,17 +80,30 @@ public void init(IDSCPv2Settings serverSettings) { } @Override - public void newConnectionHandler(IDSCPv2Connection connection) { - System.out.println("User: New connection with id " + connection.getConnectionId()); - } + public void newConnectionHandler(Idscp2Connection connection) { + System.out.println("Server: New connection with id " + connection.getConnectionId()); + connection.addConnectionListener(new IdscpConnectionListener() { + @Override + public void onError(String error) { + System.out.println("Server error occurred: " + error); + } - @Override - public void errorHandler(String error) { - System.out.println("User: Error occurred: " + error); + @Override + public void onClose(String connectionId) { + System.out.println("Server: Connection with id " + connectionId + " has been closed"); + } + }); + connection.addGenericMessageListener(((type, data) -> System.out.println( + "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); + connection.addMessageListener("ping", ((type, data) -> { + System.out.println("Received ping message:\n" + new String(data, StandardCharsets.UTF_8)); + System.out.println("Sending PONG..."); + connection.send("pong", "PONG".getBytes(StandardCharsets.UTF_8)); + })); } @Override - public void connectionClosedHandler(String connectionId) { - System.out.println("User: Connection with id " + connectionId + " has been closed"); + public void errorHandler(String error) { + System.out.println("Server error occurred: " + error); } } From 49ad37230a764bccf7b5e6fc091be828d3429586 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Mon, 18 May 2020 21:56:27 +0200 Subject: [PATCH 072/237] Naming and code cleanups --- idscp2/bnd.bnd | 4 +- ...iator.java => Idscp2EndpointListener.java} | 10 +- .../daps/DefaultDapsDriver.java | 41 ++++--- .../daps/DefaultDapsDriverConfig.java | 2 +- .../daps/SecurityRequirements.java | 2 +- .../CustomX509ExtendedKeyManager.java | 6 +- .../keystores/PreConfiguration.java | 6 +- .../rat/dummy/RatProverDummy.java | 2 +- .../rat/dummy/RatVerifierDummy.java | 2 +- .../rat/{TPM2d => tpm2d}/TPM2dHelper.java | 9 +- .../TPM2dMessageFactory.java} | 5 +- .../rat/{TPM2d => tpm2d}/TPM2dProver.java | 12 +- .../TPM2dProverConfig.java} | 13 ++- .../rat/{TPM2d => tpm2d}/TPM2dSocket.java | 3 +- .../rat/{TPM2d => tpm2d}/TPM2dVerifier.java | 12 +- .../TPM2dVerifierConfig.java} | 13 ++- .../secure_channel/NativeTLSDriver.java | 15 +-- ...java => TLSSessionVerificationHelper.java} | 21 ++-- .../secure_channel/TlsConstants.java | 2 +- .../client/InputListenerThread.java | 2 +- .../secure_channel/client/TLSClient.java | 22 ++-- .../secure_channel/server/TLSServer.java | 23 ++-- .../server/TLSServerThread.java | 37 ++++--- .../drivers/interfaces/RatProverDriver.java | 2 +- .../drivers/interfaces/RatVerifierDriver.java | 2 +- .../interfaces/SecureChannelDriver.java | 18 +-- .../drivers/interfaces/SecureServer.java | 2 +- ...Pv2Exception.java => Idscp2Exception.java} | 8 +- .../example/Idscp2ClientInitiator.java} | 38 ++++--- .../example/Idscp2ServerInitiator.java} | 52 ++++----- .../ids/idscp2/example}/RunTLSClient.java | 8 +- .../ids/idscp2/example}/RunTLSServer.java | 10 +- .../idscp2/idscp_core/Idscp2Connection.java | 26 ++--- ...ner.java => Idscp2ConnectionListener.java} | 4 +- ...eFactory.java => Idscp2MessageHelper.java} | 7 +- ...stener.java => Idscp2MessageListener.java} | 2 +- .../ids/idscp2/idscp_core/IdscpConstants.java | 10 -- ...SCPv2Callback.java => Idscp2Callback.java} | 12 +- ...guration.java => Idscp2Configuration.java} | 79 +++++++------- ...SCPv2Settings.java => Idscp2Settings.java} | 16 ++- .../finite_state_machine/Event.java | 12 +- .../idscp_core/finite_state_machine/FSM.java | 44 ++++---- .../finite_state_machine/FsmListener.java | 6 +- .../InternalControlMessage.java | 2 +- .../finite_state_machine/State.java | 2 +- .../finite_state_machine/StateClosed.java | 8 +- .../StateEstablished.java | 28 ++--- .../StateWaitForDatAndRat.java | 34 +++--- .../StateWaitForDatAndRatVerifier.java | 26 ++--- .../StateWaitForHello.java | 35 +++--- .../finite_state_machine/StateWaitForRat.java | 34 +++--- .../StateWaitForRatProver.java | 30 ++--- .../StateWaitForRatVerifier.java | 28 ++--- .../finite_state_machine/TimerThread.java | 2 +- .../finite_state_machine/Transition.java | 2 +- .../idscp_server/IDSCPv2Server.java | 103 ------------------ .../idscp_core/idscp_server/Idscp2Server.java | 73 +++++++++++++ .../idscp_server/IdscpServerListener.java | 20 ---- .../rat_registry/RatProverDriverRegistry.java | 6 +- .../RatVerifierDriverRegistry.java | 6 +- .../secure_channel/SecureChannel.java | 7 +- idscp2/src/main/proto/idscpv2.proto | 2 +- 62 files changed, 519 insertions(+), 551 deletions(-) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/{IDSCPv2Initiator.java => Idscp2EndpointListener.java} (51%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d => tpm2d}/TPM2dHelper.java (99%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d/TpmMessageFactory.java => tpm2d/TPM2dMessageFactory.java} (98%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d => tpm2d}/TPM2dProver.java (95%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d/Tpm2dProverConfig.java => tpm2d/TPM2dProverConfig.java} (83%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d => tpm2d}/TPM2dSocket.java (99%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d => tpm2d}/TPM2dVerifier.java (96%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/{TPM2d/Tpm2dVerifierConfig.java => tpm2d/TPM2dVerifierConfig.java} (89%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/{TlsSessionVerificationHelper.java => TLSSessionVerificationHelper.java} (95%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/{IDSCPv2Exception.java => Idscp2Exception.java} (50%) rename idscp2/src/{test/java/IDSCPv2ClientInitiator.java => main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java} (71%) rename idscp2/src/{test/java/IDSCPv2ServerInitiator.java => main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java} (67%) rename idscp2/src/{test/java => main/java/de/fhg/aisec/ids/idscp2/example}/RunTLSClient.java (68%) rename idscp2/src/{test/java => main/java/de/fhg/aisec/ids/idscp2/example}/RunTLSServer.java (64%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/{IdscpConnectionListener.java => Idscp2ConnectionListener.java} (78%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/{IdscpMessageFactory.java => Idscp2MessageHelper.java} (96%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/{IdscpMessageListener.java => Idscp2MessageListener.java} (83%) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/{IDSCPv2Callback.java => Idscp2Callback.java} (69%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/{IDSCPv2Configuration.java => Idscp2Configuration.java} (57%) rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/{IDSCPv2Settings.java => Idscp2Settings.java} (89%) delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java diff --git a/idscp2/bnd.bnd b/idscp2/bnd.bnd index 379857898..cf8d3ba32 100644 --- a/idscp2/bnd.bnd +++ b/idscp2/bnd.bnd @@ -1,7 +1,7 @@ Bundle-Name: IDS :: IDS Communication Protocol Bundle-Description: IDS Communication Protocol Export-Package: \ - de.fhg.aisec.ids.comm* + de.fhg.aisec.ids.idscp2* Import-Package: \ !org.checkerframework.checker*,\ - * \ No newline at end of file + * \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java similarity index 51% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java index 076d58289..dda504f89 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/IDSCPv2Initiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java @@ -3,20 +3,20 @@ import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; /** - * An interface for the IDSCPv2Initiator class, that implements callback functions that notifies + * An interface for the Idscp2EndpointListener class, that implements callback functions that notifies * the user about new connections, errors and closed connections * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public interface IDSCPv2Initiator { +public interface Idscp2EndpointListener { /* * Called when a new connection is established */ - void newConnectionHandler(Idscp2Connection connection); + void onConnection(Idscp2Connection connection); /* - * Called when an error occurred in the underlying IDSCPv2 protocol + * Called when an error occurred in the underlying IDSCP2 protocol */ - void errorHandler(String error); + void onError(String error); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 62ca603af..3c6279d70 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -4,22 +4,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; -import java.io.IOException; -import java.security.Key; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.Date; -import java.util.concurrent.TimeUnit; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509ExtendedTrustManager; -import okhttp3.FormBody; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; +import okhttp3.*; import org.jose4j.http.Get; import org.jose4j.jwa.AlgorithmConstraints; import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; @@ -36,6 +21,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import java.io.IOException; +import java.security.Key; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.Date; +import java.util.concurrent.TimeUnit; + /** * Default DAPS Driver Implementation for requesting valid dynamicAttributeToken and verifying DAT * @@ -44,12 +41,12 @@ public class DefaultDapsDriver implements DapsDriver { private static final Logger LOG = LoggerFactory.getLogger(DefaultDapsDriver.class); - private SSLSocketFactory sslSocketFactory; //ssl socket factory can be reused - private X509ExtendedTrustManager trustManager; //trust manager can be reused - private Key privateKey; //private key can be reused - private String connectorUUID; - private String dapsUrl; - private String targetAudience = "IDS_Connector"; + private final SSLSocketFactory sslSocketFactory; //ssl socket factory can be reused + private final X509ExtendedTrustManager trustManager; //trust manager can be reused + private final Key privateKey; //private key can be reused + private final String connectorUUID; + private final String dapsUrl; + private final String targetAudience = "IDS_Connector"; public DefaultDapsDriver(DefaultDapsDriverConfig config) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java index 63e28c2b5..9164d72ad 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java @@ -18,7 +18,7 @@ public class DefaultDapsDriverConfig { @NonNull private String connectorUUID = ""; public static class Builder { - @NonNull private DefaultDapsDriverConfig config = new DefaultDapsDriverConfig(); + @NonNull private final DefaultDapsDriverConfig config = new DefaultDapsDriverConfig(); @NonNull public Builder setDapsUrl(String dapsUrl) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java index 5d62a7b2f..275f82c19 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -14,7 +14,7 @@ public class SecurityRequirements { private int auditLogging; public static class Builder { - @NonNull private SecurityRequirements requirements = new SecurityRequirements(); + @NonNull private final SecurityRequirements requirements = new SecurityRequirements(); @NonNull public Builder setAuditLogging(int auditLogging) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index 0719a7783..67ac13189 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -30,7 +30,7 @@ public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ // update on java 11. As we have to check in chooseClientAliases() and chooseServerAlias() if the alias exists in // the keystore and we cannot access the cached aliases without an overwritten X509KeyManagerImpl instance, we will // also cache the aliases and its properties in the following HashMap. - private HashMap cachedAliases = new HashMap<>(); + private final HashMap cachedAliases = new HashMap<>(); CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate){ super(); @@ -137,8 +137,8 @@ public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEn private static class CachedAliasValue { - private String keyType; //key algorithm type name - private Principal issuer; //certificate issuer + private final String keyType; //key algorithm type name + private final Principal issuer; //certificate issuer CachedAliasValue(String keyType, Principal issuer){ this.keyType = keyType; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index e02a0745a..93550c54b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -1,6 +1,5 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores; -import java.util.Date; import javax.net.ssl.*; import java.io.IOException; import java.io.InputStream; @@ -9,6 +8,7 @@ import java.security.*; import java.security.cert.*; import java.util.Arrays; +import java.util.Date; import java.util.Set; import java.util.stream.Collectors; @@ -68,7 +68,7 @@ public static KeyManager[] getX509ExtKeyManager( String keyType ) { try ( - InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)); + InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)) ) { /* create KeyManager for remote authentication */ final KeyManager[] myKeyManager; @@ -108,7 +108,7 @@ public static Key getKey( String keyAlias ) { try ( - InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)); + InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)) ) { /* create KeyManager for remote authentication */ KeyStore keystore = KeyStore.getInstance("JKS"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 51a270b2e..87fbc1ca6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -16,7 +16,7 @@ public class RatProverDummy extends RatProverDriver { private static final Logger LOG = LoggerFactory.getLogger(RatProverDummy.class); - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); public RatProverDummy(){ super(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index 6a9a927f2..9127ddfae 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -16,7 +16,7 @@ public class RatVerifierDummy extends RatVerifierDriver { private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDummy.class); - private BlockingQueue queue = new LinkedBlockingQueue<>(); + private final BlockingQueue queue = new LinkedBlockingQueue<>(); public RatVerifierDummy(){ super(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java similarity index 99% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java index b589ec768..0639288dc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java @@ -1,12 +1,13 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.security.cert.Certificate; import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.security.cert.Certificate; + public class TPM2dHelper { private static final Logger LOG = LoggerFactory.getLogger(TPM2dHelper.class); private static final SecureRandom sr = new SecureRandom(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java similarity index 98% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java index a59a83ccd..effae50fe 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TpmMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java @@ -1,9 +1,10 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; import com.google.protobuf.ByteString; import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d.Code; + import java.util.List; /** @@ -11,7 +12,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TpmMessageFactory { +public class TPM2dMessageFactory { static Tpm2dMessageWrapper getAttestationChallengeMessage( byte[] nonce, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java similarity index 95% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java index 33a1aea39..b2ff18fb0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; @@ -54,7 +54,7 @@ public class TPM2dProver extends RatProverDriver { */ private final BlockingQueue queue = new LinkedBlockingQueue<>(); - private Tpm2dProverConfig config = new Tpm2dProverConfig.Builder().build(); + private TPM2dProverConfig config = new TPM2dProverConfig.Builder().build(); public TPM2dProver(){ super(); @@ -62,11 +62,11 @@ public TPM2dProver(){ @Override public void setConfig(Object config) { - if (config instanceof Tpm2dProverConfig) { + if (config instanceof TPM2dProverConfig) { if (LOG.isDebugEnabled()) { LOG.debug("Set rat prover config"); } - this.config = (Tpm2dProverConfig) config; + this.config = (TPM2dProverConfig) config; } else { if (LOG.isWarnEnabled()) { LOG.warn("Invalid prover config"); @@ -134,7 +134,7 @@ public void run() { config.getRemoteCertificate()); // generate RemoteToTPM2dRequest - RemoteToTpm2d tpmRequest = TpmMessageFactory.getRemoteToTPM2dMessage( + RemoteToTpm2d tpmRequest = TPM2dMessageFactory.getRemoteToTPM2dMessage( challenge.getAtype(), hash, challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 @@ -152,7 +152,7 @@ public void run() { } // create Tpm2dResponse - byte[] response = TpmMessageFactory.getAttestationResponseMessage(tpmResponse) + byte[] response = TPM2dMessageFactory.getAttestationResponseMessage(tpmResponse) .toByteArray(); if (LOG.isDebugEnabled()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java similarity index 83% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java index dd904d1f4..b9a64a8c8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dProverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java @@ -1,25 +1,26 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; -import java.security.cert.Certificate; import org.checkerframework.checker.nullness.qual.NonNull; +import java.security.cert.Certificate; + /** * A configuration class for TPM2d RatPriver driver * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Tpm2dProverConfig { +public class TPM2dProverConfig { private Certificate remoteCertificate; @NonNull private String tpm2dHost; - private Tpm2dProverConfig() { + private TPM2dProverConfig() { tpm2dHost = System.getenv("TPM_HOST") != null ? System.getenv("TPM_HOST") : "localhost"; } public static class Builder { - private static Tpm2dProverConfig config = new Tpm2dProverConfig(); + private static final TPM2dProverConfig config = new TPM2dProverConfig(); @NonNull public Builder setRemoteCertificate(Certificate remoteCert) { @@ -33,7 +34,7 @@ public Builder setTpmHost(String host) { return this; } - public Tpm2dProverConfig build() { + public TPM2dProverConfig build() { return config; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java similarity index 99% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java index 68d868816..943de0690 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dSocket.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java @@ -1,7 +1,8 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d; import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dToRemote; + import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java similarity index 96% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java index b6f0951dc..3b65cc1a8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java @@ -1,4 +1,4 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; @@ -65,7 +65,7 @@ public class TPM2dVerifier extends RatVerifierDriver { */ private final BlockingQueue queue = new LinkedBlockingQueue<>(); - private Tpm2dVerifierConfig config = new Tpm2dVerifierConfig.Builder().build(); + private TPM2dVerifierConfig config = new TPM2dVerifierConfig.Builder().build(); public TPM2dVerifier(){ super(); @@ -73,9 +73,9 @@ public TPM2dVerifier(){ @Override public void setConfig(Object config) { - if (config instanceof Tpm2dVerifierConfig) { + if (config instanceof TPM2dVerifierConfig) { LOG.debug("Set rat verifier config"); - this.config = (Tpm2dVerifierConfig) config; + this.config = (TPM2dVerifierConfig) config; } else { LOG.warn("Invalid config"); } @@ -96,7 +96,7 @@ public void run(){ byte[] nonce = TPM2dHelper.generateNonce(20); // send challenge as RAT Verifier Message - byte[] ratChallenge = TpmMessageFactory.getAttestationChallengeMessage( + byte[] ratChallenge = TPM2dMessageFactory.getAttestationChallengeMessage( nonce, config.getExpectedAType(), config.getExpectedAttestationMask()).toByteArray(); fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratChallenge); @@ -150,7 +150,7 @@ public void run(){ // create and send rat result LOG.debug("Send rat result to remote prover"); - byte[] ratResult = TpmMessageFactory.getAttestationResultMessage(result).toByteArray(); + byte[] ratResult = TPM2dMessageFactory.getAttestationResultMessage(result).toByteArray(); fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratResult); // notify fsm about result diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java similarity index 89% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java index 9c5060b24..3dee225a5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/TPM2d/Tpm2dVerifierConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java @@ -1,24 +1,25 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d; +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; import de.fhg.aisec.ids.messages.Tpm2dAttestation.IdsAttestationType; +import org.checkerframework.checker.nullness.qual.NonNull; + import java.net.URI; import java.net.URISyntaxException; import java.security.cert.Certificate; -import org.checkerframework.checker.nullness.qual.NonNull; /** * A configuration class for TPM2d RatVerifier Driver * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Tpm2dVerifierConfig { +public class TPM2dVerifierConfig { private Certificate localCertificate; @NonNull private URI ttpUri; @NonNull private IdsAttestationType expectedAType = IdsAttestationType.BASIC; private int expectedAttestationMask = 0; - private Tpm2dVerifierConfig() { + private TPM2dVerifierConfig() { try { ttpUri = new URI("https://invalid-ttp-uri/rat-verify"); } catch (URISyntaxException e) { @@ -27,7 +28,7 @@ private Tpm2dVerifierConfig() { } public static class Builder { - private static Tpm2dVerifierConfig config = new Tpm2dVerifierConfig(); + private static final TPM2dVerifierConfig config = new TPM2dVerifierConfig(); @NonNull public Builder setTtpUri(URI ttpUri) { @@ -52,7 +53,7 @@ public Builder setExpectedAttestationMask(int mask) { return this; } - public Tpm2dVerifierConfig build() { + public TPM2dVerifierConfig build() { return config; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 8368c96d9..47190ab5c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -4,9 +4,9 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server.TLSServer; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +14,7 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; /** * An implementation of SecureChannelDriver interface on TLSv1.3 @@ -27,7 +28,7 @@ public class NativeTLSDriver implements SecureChannelDriver { * Asynchronous client connect to a TLS server */ @Override - public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { + public void connect(Idscp2Settings settings, Idscp2Callback callback) { try { TLSClient tlsClient = new TLSClient(settings, callback); tlsClient.connect(settings.getHost(), settings.getServerPort()); @@ -46,10 +47,10 @@ public void connect(IDSCPv2Settings settings, IDSCPv2Callback callback) { * return null on failure */ @Override - public SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, - IdscpServerListener idscpServerCallback) { + public SecureServer listen(Idscp2Settings settings, Idscp2Callback configCallback, + CompletableFuture connectionPromise) { try { - TLSServer tlsServer = new TLSServer(settings, configCallback, idscpServerCallback); + TLSServer tlsServer = new TLSServer(settings, configCallback, connectionPromise); tlsServer.start(); return tlsServer; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java similarity index 95% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java index 6127dcd7a..9a3952894 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsSessionVerificationHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java @@ -1,20 +1,17 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; -import java.security.cert.Certificate; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import java.security.cert.*; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A class for verifying an established TLS Session on application layer @@ -22,8 +19,8 @@ * * @author Leon Beckmann (leon.beckmannn@aisec.fraunhofer.de) */ -public class TlsSessionVerificationHelper { - private static final Logger LOG = LoggerFactory.getLogger(TlsSessionVerificationHelper.class); +public class TLSSessionVerificationHelper { + private static final Logger LOG = LoggerFactory.getLogger(TLSSessionVerificationHelper.class); private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; @@ -60,7 +57,7 @@ public static void verifyTlsSession(SSLSession sslSession) throws SSLPeerUnverif * According to RFC6125, hostname verification should be done against the certificate's * subject alternative name's (SANs) dNSName field or the SANs IPAddress. In some legacy * implementations, the check is done against the certificate's commonName, but this is - * deprecated for quite a while and is therefore not supported anymore in te IDSCPv2 protocol. + * deprecated for quite a while and is therefore not supported anymore in te IDSCP2 protocol. */ Collection> sans = peerCert.getSubjectAlternativeNames(); if (sans == null) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java index f9662adcf..bbbec4b60 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java @@ -113,5 +113,5 @@ public final class TlsConstants { "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ }; - private TlsConstants() {}; + private TlsConstants() {} } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index b3a0ba1ec..e3f60a084 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -14,7 +14,7 @@ */ public class InputListenerThread extends Thread implements InputListener { - private DataInputStream in; + private final DataInputStream in; private DataAvailableListener listener = null; //no race conditions, could be empty list private volatile boolean running = true; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index d65d73453..b3c16f91e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -1,10 +1,10 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsSessionVerificationHelper; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -21,7 +21,7 @@ import java.util.concurrent.CountDownLatch; /** - * A TLS Client that notifies an IDSCPv2Configuration when a secure channel was created and the + * A TLS Client that notifies an Idscp2Configuration when a secure channel was created and the * TLS handshake is done. The client is notified from an InputListenerThread when new data are * available and transfer it to the SecureChannelListener * @@ -31,15 +31,15 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListener, SecureChannelEndpoint { private static final Logger LOG = LoggerFactory.getLogger(TLSClient.class); - private Socket clientSocket; + private final Socket clientSocket; private DataOutputStream out; private InputListenerThread inputListenerThread; private SecureChannelListener listener; //race conditions are avoided using CountDownLatch - private CountDownLatch listenerLatch = new CountDownLatch(1); - private IDSCPv2Callback callback; //race conditions are avoided because callback is initialized in constructor + private final CountDownLatch listenerLatch = new CountDownLatch(1); + private final Idscp2Callback callback; - public TLSClient(IDSCPv2Settings clientSettings, IDSCPv2Callback callback) + public TLSClient(Idscp2Settings clientSettings, Idscp2Callback callback) throws IOException, KeyManagementException, NoSuchAlgorithmException{ this.callback = callback; /* init TLS Client */ @@ -195,7 +195,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) // verify tls session on application layer: hostname verification, certificate validity try { - TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); + TLSSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); LOG.debug("TLS session is valid"); } catch (SSLPeerUnverifiedException e) { if (LOG.isWarnEnabled()) { @@ -207,7 +207,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) } //Create secure channel, register secure channel as message listener and provide it to - // IDSCPv2 Configuration. + // IDSCP2 Configuration. //Start Input Listener SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 63f5ecdd9..17bba4e93 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -1,11 +1,11 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,9 +15,10 @@ import java.net.SocketTimeoutException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.concurrent.CompletableFuture; /** - * A TLS Server that listens on a given port from the IDSCPv2Settings and create new + * A TLS Server that listens on a given port from the Idscp2Settings and create new * TLSServerThreads for incoming connections * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -27,14 +28,14 @@ public class TLSServer extends Thread implements SecureServer { private volatile boolean isRunning = false; private final ServerSocket serverSocket; - private final IDSCPv2Callback idscpConfigCallback; //no race conditions - private final IdscpServerListener idscpServerCallback; + private final Idscp2Callback idscpConfigCallback; //no race conditions + private final CompletableFuture connectionPromise; - public TLSServer(IDSCPv2Settings serverSettings, IDSCPv2Callback configCallback, - IdscpServerListener idscpServerCallback) + public TLSServer(Idscp2Settings serverSettings, Idscp2Callback configCallback, + CompletableFuture connectionPromise) throws IOException, NoSuchAlgorithmException, KeyManagementException { this.idscpConfigCallback = configCallback; - this.idscpServerCallback = idscpServerCallback; + this.connectionPromise = connectionPromise; /* init server for TCP/TLS communication */ @@ -110,7 +111,7 @@ public void run(){ //start new server thread LOG.debug("New TLS client has connected. Create new server session"); - TLSServerThread server = new TLSServerThread(sslSocket, idscpConfigCallback, idscpServerCallback); + TLSServerThread server = new TLSServerThread(sslSocket, idscpConfigCallback, connectionPromise); sslSocket.addHandshakeCompletedListener(server); server.start(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index 3ed6c0ff5..e82c35c33 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -1,24 +1,28 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsSessionVerificationHelper; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; -import javax.net.ssl.SSLPeerUnverifiedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocket; -import java.io.*; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; import java.net.SocketTimeoutException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; /** - * A TLSServerThread that notifies an IDSCPv2Config when a secure channel was created and the + * A TLSServerThread that notifies an IDSCP2Config when a secure channel was created and the * TLS handshake is done * * When new data are available the serverThread transfers it to the SecureChannelListener @@ -28,21 +32,22 @@ public class TLSServerThread extends Thread implements HandshakeCompletedListener, SecureChannelEndpoint { private static final Logger LOG = LoggerFactory.getLogger(TLSServerThread.class); - private SSLSocket sslSocket; + private final SSLSocket sslSocket; private volatile boolean running = true; private DataInputStream in; private DataOutputStream out; private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch - private IDSCPv2Callback configCallback; //no race conditions - private IdscpServerListener idscpServerCallback; //no race conditions - private CountDownLatch listenerLatch = new CountDownLatch(1); - private CountDownLatch tlsVerificationLatch = new CountDownLatch(1); + private final Idscp2Callback configCallback; + private final CompletableFuture connectionPromise; + private final CountDownLatch listenerLatch = new CountDownLatch(1); + private final CountDownLatch tlsVerificationLatch = new CountDownLatch(1); - TLSServerThread(SSLSocket sslSocket, IDSCPv2Callback configCallback, IdscpServerListener idscpServerCallback){ + TLSServerThread(SSLSocket sslSocket, Idscp2Callback configCallback, + CompletableFuture connectionPromise){ this.sslSocket = sslSocket; this.configCallback = configCallback; - this.idscpServerCallback = idscpServerCallback; + this.connectionPromise = connectionPromise; try { //set timout for blocking read @@ -176,7 +181,7 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) // verify tls session on application layer: hostname verification, certificate validity try { - TlsSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); + TLSSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); LOG.debug("TLS session is valid"); tlsVerificationLatch.countDown(); } catch (SSLPeerUnverifiedException e) { @@ -188,10 +193,10 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) return; } - //provide secure channel to IDSCPv2 Config and register secure channel as listener + //provide secure channel to IDSCP2 Config and register secure channel as listener SecureChannel secureChannel = new SecureChannel(this); this.listener = secureChannel; listenerLatch.countDown(); - configCallback.secureChannelListenHandler(secureChannel, idscpServerCallback); + configCallback.secureChannelListenHandler(secureChannel, connectionPromise); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index 08e3a707d..e26bc966a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -17,7 +17,7 @@ public abstract class RatProverDriver extends Thread{ protected FsmListener fsmListener; /* - * Delegate an IDSCPv2 message to the RatProver driver + * Delegate an IDSCP2 message to the RatProver driver */ public void delegate(byte[] message){} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 362169234..79686cda7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -17,7 +17,7 @@ public abstract class RatVerifierDriver extends Thread{ protected FsmListener fsmListener; /* - * Delegate the IDSCPv2 message to the RatVerifier driver + * Delegate the IDSCP2 message to the RatVerifier driver */ public void delegate(byte[] message){} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 3adab7967..02a3f0d0d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -1,12 +1,14 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Callback; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; + +import java.util.concurrent.CompletableFuture; /** - * An interface for the IDSCPv2 SecureChannelDriver class, that implements a connect() function - * for IDSCPv2 clients and a listen() function for IDSCPv2 servers to connect the underlying layer + * An interface for the IDSCP2 SecureChannelDriver class, that implements a connect() function + * for IDSCP2 clients and a listen() function for IDSCP2 servers to connect the underlying layer * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -15,11 +17,11 @@ public interface SecureChannelDriver { /* * Asynchronous method to create a secure connection to a secure server */ - void connect(IDSCPv2Settings settings, IDSCPv2Callback configCallback); + void connect(Idscp2Settings settings, Idscp2Callback configCallback); /* * Starting a secure server */ - SecureServer listen(IDSCPv2Settings settings, IDSCPv2Callback configCallback, - IdscpServerListener idscpServerCallback); + SecureServer listen(Idscp2Settings settings, Idscp2Callback configCallback, + CompletableFuture connectionPromise); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java index 260439be5..af0f3913d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureServer.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; /** - * An interface for the IDSCPv2 Secure Server + * An interface for the IDSCP2 Secure Server * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java similarity index 50% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java index ad16f97f3..9c19390ea 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/IDSCPv2Exception.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java @@ -1,16 +1,16 @@ package de.fhg.aisec.ids.idscp2.error; /** - * IDSCPv2 Exception + * IDSCP2 Exception * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IDSCPv2Exception extends Exception{ - public IDSCPv2Exception(String message) { +public class Idscp2Exception extends Exception{ + public Idscp2Exception(String message) { super(message); } - public IDSCPv2Exception(String message, Throwable cause) { + public Idscp2Exception(String message, Throwable cause) { super(message, cause); } } diff --git a/idscp2/src/test/java/IDSCPv2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java similarity index 71% rename from idscp2/src/test/java/IDSCPv2ClientInitiator.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index 06ab74b40..b3a0d4f6f 100644 --- a/idscp2/src/test/java/IDSCPv2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -1,27 +1,29 @@ -import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +package de.fhg.aisec.ids.idscp2.example; + +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dProver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dVerifier; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dProverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpConnectionListener; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import java.nio.charset.StandardCharsets; -public class IDSCPv2ClientInitiator implements IDSCPv2Initiator { +public class Idscp2ClientInitiator implements Idscp2EndpointListener { - public void init(IDSCPv2Settings settings){ + public void init(Idscp2Settings settings){ SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -43,14 +45,14 @@ public void init(IDSCPv2Settings settings){ RatProverDriverRegistry.getInstance().registerDriver( "TPM2d", TPM2dProver.class, - new Tpm2dProverConfig.Builder().build() + new TPM2dProverConfig.Builder().build() ); RatVerifierDriverRegistry.getInstance().registerDriver( "TPM2d", TPM2dVerifier.class, - new Tpm2dVerifierConfig.Builder().build() + new TPM2dVerifierConfig.Builder().build() ); - IDSCPv2Configuration clientConfig = new IDSCPv2Configuration( + Idscp2Configuration clientConfig = new Idscp2Configuration( this, dapsDriver, secureChannelDriver, @@ -62,12 +64,12 @@ public void init(IDSCPv2Settings settings){ } @Override - public void newConnectionHandler(Idscp2Connection connection) { + public void onConnection(Idscp2Connection connection) { System.out.println("Client: New connection with id " + connection.getConnectionId()); - connection.addConnectionListener(new IdscpConnectionListener() { + connection.addConnectionListener(new Idscp2ConnectionListener() { @Override public void onError(String error) { - System.out.println("Client error occurred: " + error); + System.out.println("Client connection error occurred: " + error); } @Override @@ -85,7 +87,7 @@ public void onClose(String connectionId) { } @Override - public void errorHandler(String error) { - System.out.println("Client error occurred: " + error); + public void onError(String error) { + System.out.println("Client endpoint error occurred: " + error); } } diff --git a/idscp2/src/test/java/IDSCPv2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java similarity index 67% rename from idscp2/src/test/java/IDSCPv2ServerInitiator.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index 3b62e7961..ff89f928f 100644 --- a/idscp2/src/test/java/IDSCPv2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -1,32 +1,32 @@ -import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; +package de.fhg.aisec.ids.idscp2.example; + +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dProver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.TPM2dVerifier; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dProverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.TPM2d.Tpm2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpConnectionListener; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import java.nio.charset.StandardCharsets; -public class IDSCPv2ServerInitiator implements IDSCPv2Initiator { - - //private ConcurrentHashMap connections = new ConcurrentHashMap<>(); +public class Idscp2ServerInitiator implements Idscp2EndpointListener { - public void init(IDSCPv2Settings serverSettings) { + public void init(Idscp2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = @@ -47,14 +47,14 @@ public void init(IDSCPv2Settings serverSettings) { "Dummy", RatVerifierDummy.class, null); RatProverDriverRegistry.getInstance().registerDriver( "TPM2d", TPM2dProver.class, - new Tpm2dProverConfig.Builder().build() + new TPM2dProverConfig.Builder().build() ); RatVerifierDriverRegistry.getInstance().registerDriver( "TPM2d", TPM2dVerifier.class, - new Tpm2dVerifierConfig.Builder().build() + new TPM2dVerifierConfig.Builder().build() ); - IDSCPv2Configuration idscpServerConfig = new IDSCPv2Configuration( + Idscp2Configuration idscpServerConfig = new Idscp2Configuration( this, dapsDriver, secureChannelDriver, @@ -63,10 +63,10 @@ public void init(IDSCPv2Settings serverSettings) { serverSettings.getRatTimeoutDelay() ); - IDSCPv2Server idscPv2Server; + Idscp2Server idscp2Server; try { - idscPv2Server = idscpServerConfig.listen(serverSettings); - } catch (IDSCPv2Exception e) { + idscp2Server = idscpServerConfig.listen(serverSettings); + } catch (Idscp2Exception e) { //e.printStackTrace(); return; } @@ -76,16 +76,16 @@ public void init(IDSCPv2Settings serverSettings) { } catch (Exception e){ return; } - idscPv2Server.terminate(); + idscp2Server.terminate(); } @Override - public void newConnectionHandler(Idscp2Connection connection) { + public void onConnection(Idscp2Connection connection) { System.out.println("Server: New connection with id " + connection.getConnectionId()); - connection.addConnectionListener(new IdscpConnectionListener() { + connection.addConnectionListener(new Idscp2ConnectionListener() { @Override public void onError(String error) { - System.out.println("Server error occurred: " + error); + System.out.println("Server connection error occurred: " + error); } @Override @@ -103,7 +103,7 @@ public void onClose(String connectionId) { } @Override - public void errorHandler(String error) { - System.out.println("Server error occurred: " + error); + public void onError(String error) { + System.out.println("Server endpoint error occurred: " + error); } } diff --git a/idscp2/src/test/java/RunTLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java similarity index 68% rename from idscp2/src/test/java/RunTLSClient.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java index 1e0983803..c97741f93 100644 --- a/idscp2/src/test/java/RunTLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java @@ -1,11 +1,13 @@ -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +package de.fhg.aisec.ids.idscp2.example; + +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; public class RunTLSClient { public static void main(String[] args){ //start client - IDSCPv2Settings settings = new IDSCPv2Settings.Builder() + Idscp2Settings settings = new Idscp2Settings.Builder() .setKeyStore(RunTLSClient.class.getClassLoader(). getResource("ssl/aisecconnector1-keystore.jks").getPath()) .setTrustStore(RunTLSClient.class.getClassLoader(). @@ -15,7 +17,7 @@ public static void main(String[] args){ .setRatTimeoutDelay(10) .build(); - IDSCPv2ClientInitiator initiator = new IDSCPv2ClientInitiator(); + Idscp2ClientInitiator initiator = new Idscp2ClientInitiator(); initiator.init(settings); } } diff --git a/idscp2/src/test/java/RunTLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java similarity index 64% rename from idscp2/src/test/java/RunTLSServer.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java index 1635158b8..2816fb636 100644 --- a/idscp2/src/test/java/RunTLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java @@ -1,10 +1,12 @@ -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.IDSCPv2Settings; +package de.fhg.aisec.ids.idscp2.example; -public class RunTLSServer{ +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; + +public class RunTLSServer { public static void main(String[] argv){ - IDSCPv2Settings settings = new IDSCPv2Settings.Builder() + Idscp2Settings settings = new Idscp2Settings.Builder() .setKeyStore(RunTLSClient.class.getClassLoader(). getResource("ssl/aisecconnector1-keystore.jks").getPath()) .setTrustStore(RunTLSServer.class.getClassLoader(). @@ -14,7 +16,7 @@ public static void main(String[] argv){ .setRatTimeoutDelay(14) .build(); - IDSCPv2ServerInitiator initiator = new IDSCPv2ServerInitiator(); + Idscp2ServerInitiator initiator = new Idscp2ServerInitiator(); initiator.init(settings); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index 0419168b1..e5e7cea90 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -8,7 +8,7 @@ import java.util.*; /** - * The IDSCPv2 Connection class holds connections between connectors + * The IDSCP2 Connection class holds connections between connectors * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) * @author Michael Lux (michael.lux@aisec.fraunhofer.de) @@ -18,9 +18,9 @@ public class Idscp2Connection { private final FSM fsm; private final String connectionId; - private final Set connectionListeners = new HashSet<>(); - private final Set genericMessageListeners = new HashSet<>(); - private final Map> messageListeners = new HashMap<>(); + private final Set connectionListeners = new HashSet<>(); + private final Set genericMessageListeners = new HashSet<>(); + private final Map> messageListeners = new HashMap<>(); public Idscp2Connection(FSM fsm, String connectionId) { this.fsm = fsm; @@ -51,7 +51,7 @@ public void onMessage(String type, byte[] msg) { synchronized (genericMessageListeners) { genericMessageListeners.forEach(l -> l.onMessage(type, msg)); } - Set listeners = messageListeners.get(type); + Set listeners = messageListeners.get(type); if (listeners != null) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (listeners) { @@ -78,33 +78,33 @@ public String getConnectionId() { return connectionId; } - public void addConnectionListener(IdscpConnectionListener listener) { + public void addConnectionListener(Idscp2ConnectionListener listener) { synchronized (connectionListeners) { connectionListeners.add(listener); } } - public boolean removeConnectionListener(IdscpConnectionListener listener) { + public boolean removeConnectionListener(Idscp2ConnectionListener listener) { synchronized (connectionListeners) { return connectionListeners.remove(listener); } } - public void addGenericMessageListener(IdscpMessageListener listener) { + public void addGenericMessageListener(Idscp2MessageListener listener) { synchronized (genericMessageListeners) { genericMessageListeners.add(listener); } } - public boolean removeGenericMessageListener(IdscpMessageListener listener) { + public boolean removeGenericMessageListener(Idscp2MessageListener listener) { synchronized (genericMessageListeners) { return genericMessageListeners.remove(listener); } } - public void addMessageListener(@Nullable String type, IdscpMessageListener listener) { + public void addMessageListener(@Nullable String type, Idscp2MessageListener listener) { synchronized (messageListeners) { - Set messageTypeListeners + Set messageTypeListeners = messageListeners.computeIfAbsent(type, k -> new HashSet<>()); //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (messageTypeListeners) { @@ -114,9 +114,9 @@ public void addMessageListener(@Nullable String type, IdscpMessageListener liste } } - public boolean removeMessageListener(@Nullable String type, IdscpMessageListener listener) { + public boolean removeMessageListener(@Nullable String type, Idscp2MessageListener listener) { synchronized (messageListeners) { - Set messageTypeListeners = messageListeners.get(type); + Set messageTypeListeners = messageListeners.get(type); if (messageTypeListeners == null) { return false; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java similarity index 78% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java index bd5d4b6f0..0441615d8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConnectionListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java @@ -1,10 +1,10 @@ package de.fhg.aisec.ids.idscp2.idscp_core; /** - * An IDSCP Connection Listener interface that is implemented by the IDSCPv2 Server to notify the + * An IDSCP Connection Listener interface that is implemented by the IDSCP2 Server to notify the * server about lifetimes of IDSCP connections. The server caches all active connections. */ -public interface IdscpConnectionListener { +public interface Idscp2ConnectionListener { void onError(String error); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java similarity index 96% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java index 262040c66..1c038d099 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java @@ -1,15 +1,16 @@ package de.fhg.aisec.ids.idscp2.idscp_core; import com.google.protobuf.ByteString; -import de.fhg.aisec.ids.messages.IDSCPv2.*; +import de.fhg.aisec.ids.messages.IDSCP2.*; + import java.util.Arrays; /** - * A factory for creating IDSCPv2 messages + * A factory for creating IDSCP2 messages * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IdscpMessageFactory { +public class Idscp2MessageHelper { public static IdscpMessage createIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ IdscpDat idscpDat = IdscpDat.newBuilder() diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java similarity index 83% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java index 5c3d3d39d..5576deac1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpMessageListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java @@ -3,7 +3,7 @@ /** * An interface for an IDSCP message listener */ -public interface IdscpMessageListener { +public interface Idscp2MessageListener { /* * notify the listener about new data diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java deleted file mode 100644 index 37a9c9502..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/IdscpConstants.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core; - -/** - * Global IDSCPv2 protocol constants - * - * @author Leon Beckmann(leon.beckmann@aisec.fraunhofer.de) - */ -public final class IdscpConstants { - private IdscpConstants(){}; -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java similarity index 69% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java index 9c1fd0ba5..9b7c4e948 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java @@ -1,15 +1,17 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; +import java.util.concurrent.CompletableFuture; + /** - * An callback interface that implements callback functions that notifies about new - * secureChannels + * An callback interface that implements callback functions that notify about new + * SecureChannels * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public interface IDSCPv2Callback { +public interface Idscp2Callback { /* * Notify the client about a new secure channel @@ -21,7 +23,7 @@ public interface IDSCPv2Callback { */ void secureChannelListenHandler( SecureChannel secureChannel, - IdscpServerListener idscpServer + CompletableFuture connectionPromise ); } \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java similarity index 57% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java index 0c4754fe9..3ca887848 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java @@ -1,26 +1,29 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; -import de.fhg.aisec.ids.idscp2.IDSCPv2Initiator; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; -import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IDSCPv2Server; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.IdscpServerListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.util.UUID; +import java.util.concurrent.CompletableFuture; /** - * IDSCPv2Configuration class, provides IDSCPv2 API to the User (IDSCPv2Initiator) + * Idscp2Configuration class, provides IDSCP2 API to the User (Idscp2EndpointListener) * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IDSCPv2Configuration implements IDSCPv2Callback { - private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Configuration.class); +public class Idscp2Configuration implements Idscp2Callback { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2Configuration.class); - private final IDSCPv2Initiator user; + private final Idscp2EndpointListener user; private final DapsDriver dapsDriver; private final SecureChannelDriver secureChannelDriver; private final String[] localExpectedRatCipher; @@ -28,12 +31,12 @@ public class IDSCPv2Configuration implements IDSCPv2Callback { private final int ratTimeout; - public IDSCPv2Configuration(IDSCPv2Initiator initiator, - DapsDriver dapsDriver, - SecureChannelDriver secureChannelDriver, - AttestationConfig expectedAttestation, - AttestationConfig supportedAttestation, - int ratTimeout + public Idscp2Configuration(Idscp2EndpointListener initiator, + DapsDriver dapsDriver, + SecureChannelDriver secureChannelDriver, + AttestationConfig expectedAttestation, + AttestationConfig supportedAttestation, + int ratTimeout ){ this.user = initiator; this.dapsDriver = dapsDriver; @@ -44,29 +47,29 @@ public IDSCPv2Configuration(IDSCPv2Initiator initiator, } /* - * User API to create a IDSCPv2 connection as a client + * User API to create a IDSCP2 connection as a client */ - public void connect(IDSCPv2Settings settings){ + public void connect(Idscp2Settings settings){ LOG.info("Connect to an idscpv2 server ({})", settings.getHost()); secureChannelDriver.connect(settings, this); } /* - * User API to create a new IDSCPv2 Server that starts a Secure Server that listens to new + * User API to create a new IDSCP2 Server that starts a Secure Server that listens to new * secure channels */ - public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { - LOG.info("Starting new IDSCPv2 server at port {}", settings.getServerPort()); + public Idscp2Server listen(Idscp2Settings settings) throws Idscp2Exception { + LOG.info("Starting new IDSCP2 server at port {}", settings.getServerPort()); + // requires Promise + final var connectionPromise = new CompletableFuture(); final SecureServer secureServer; - final IDSCPv2Server idscpServer = new IDSCPv2Server(); - if ((secureServer = secureChannelDriver.listen(settings, this, idscpServer)) == null){ - throw new IDSCPv2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); + if ((secureServer = secureChannelDriver.listen(settings, this, connectionPromise)) == null) { + throw new Idscp2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); } - idscpServer.setSecureServer(secureServer); - return idscpServer; + return new Idscp2Server(secureServer, connectionPromise); } /* @@ -76,14 +79,14 @@ public IDSCPv2Server listen(IDSCPv2Settings settings) throws IDSCPv2Exception { * to the user * * If the secure channel was established, a new FSM is created for this connection and the - * IDSCPv2 handshake is started. After a successful handshake, a new Idscp2Connection is + * IDSCP2 handshake is started. After a successful handshake, a new Idscp2Connection is * created and provided to the user */ @Override public void secureChannelConnectHandler(SecureChannel secureChannel) { if (secureChannel == null){ - LOG.warn("IDSCPv2 connect failed because no secure channel was established"); - user.errorHandler("IDSCPv2 connect failed because no secure channel was established"); + LOG.warn("IDSCP2 connect failed because no secure channel was established"); + user.onError("IDSCP2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, @@ -91,15 +94,15 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { try { fsm.startIdscpHandshake(); //blocking until handshake is done - } catch (IDSCPv2Exception e){ + } catch (Idscp2Exception e){ return; } String connectionId = UUID.randomUUID().toString(); Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); fsm.registerConnection(newConnection); - LOG.info("A new IDSCPv2 connection with id {} was created", connectionId); - user.newConnectionHandler(newConnection); + LOG.info("A new IDSCP2 connection with id {} was created", connectionId); + user.onConnection(newConnection); } } @@ -110,11 +113,12 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { * ignored * * If the secure channel was established, a new FSM is created for this connection and the - * IDSCPv2 handshake is started. After a successful handshake, a new Idscp2Connection is - * created and provided to the user and the IDSCPv2 server + * IDSCP2 handshake is started. After a successful handshake, a new Idscp2Connection is + * created and provided to the user and the IDSCP2 server */ @Override - public void secureChannelListenHandler(SecureChannel secureChannel, IdscpServerListener idscpServer) { + public void secureChannelListenHandler(SecureChannel secureChannel, + CompletableFuture connectionPromise) { if (secureChannel != null){ LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, @@ -122,7 +126,7 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpServerL try { fsm.startIdscpHandshake(); //blocking until handshake is done - } catch (IDSCPv2Exception e){ + } catch (Idscp2Exception e){ return; } @@ -131,8 +135,9 @@ public void secureChannelListenHandler(SecureChannel secureChannel, IdscpServerL Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); fsm.registerConnection(newConnection); LOG.info("A new idscpv2 connection with id {} was created", connectionId); - idscpServer.onConnect(newConnection); //bind connection to idscp server - user.newConnectionHandler(newConnection); + // Complete the connection promise for the IDSCP server + connectionPromise.complete(newConnection); + user.onConnection(newConnection); } else { LOG.warn("An incoming idscpv2 client connection request failed because the secure channel is null."); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java similarity index 89% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java index 963d19251..fc4021914 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/IDSCPv2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java @@ -1,15 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.units.qual.A; /** - * IDSCPv2 configuration class, contains information about keyStore and TrustStores, + * IDSCP2 configuration class, contains information about keyStore and TrustStores, * Attestation Types, host, DAPS, ... * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class IDSCPv2Settings { +public class Idscp2Settings { public static final int DEFAULT_SERVER_PORT = 8080; private int serverPort = DEFAULT_SERVER_PORT; @@ -25,9 +24,10 @@ public class IDSCPv2Settings { private AttestationConfig expectedAttestation = new AttestationConfig(); private int ratTimeoutDelay = 20; + @SuppressWarnings("unused") public static class Builder { @NonNull - private IDSCPv2Settings settings = new IDSCPv2Settings(); + private final Idscp2Settings settings = new Idscp2Settings(); @NonNull public Builder setHost(String host) { @@ -35,6 +35,12 @@ public Builder setHost(String host) { return this; } + @NonNull + public Builder setServerPort(int serverPort) { + this.settings.serverPort = serverPort; + return this; + } + @NonNull public Builder setTrustStore(String path) { this.settings.trustStorePath = path; @@ -95,7 +101,7 @@ public Builder setRatTimeoutDelay(int delay) { } @NonNull - public IDSCPv2Settings build() { + public Idscp2Settings build() { return this.settings; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index e8a2559e6..8f1b1a60f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -1,8 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; -import de.fhg.aisec.ids.messages.IDSCPv2.*; - -import javax.swing.*; +import de.fhg.aisec.ids.messages.IDSCP2.IdscpMessage; /** * An Event class for the Finite State Machine. Triggers a transition and holds @@ -16,10 +14,10 @@ public enum EventType { INTERNAL_CONTROL_MESSAGE } - private Object key; - private EventType type; - private IdscpMessage idscpMessage; - private InternalControlMessage controlMessage; + private final Object key; + private final EventType type; + private final IdscpMessage idscpMessage; + private final InternalControlMessage controlMessage; /* * Create an Event with an Internal Control Message diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 72c9abb3b..2960d7e9a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -1,14 +1,16 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import com.google.protobuf.InvalidProtocolBufferException; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.*; -import de.fhg.aisec.ids.idscp2.error.IDSCPv2Exception; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCPv2.*; +import de.fhg.aisec.ids.messages.IDSCP2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,9 +20,9 @@ import java.util.concurrent.locks.ReentrantLock; /** - * The finite state machine FSM of the IDSCPv2 protocol + * The finite state machine FSM of the IDSCP2 protocol * - * Manages IDSCPv2 Handshake, Re-Attestation, DAT-ReRequest and DAT-Re-Validation. Delivers + * Manages IDSCP2 Handshake, Re-Attestation, DAT-ReRequest and DAT-Re-Validation. Delivers * Internal Control Messages and Idscpv2Messages to the target receivers, * creates and manages the states and its transitions and implements security restriction to protect * the protocol against misuse and faulty, insecure or evil driver implementations. @@ -30,7 +32,7 @@ public class FSM implements FsmListener{ private static final Logger LOG = LoggerFactory.getLogger(FSM.class); - /* ----------- IDSCPv2 Protocol States ---------- */ + /* ----------- IDSCP2 Protocol States ---------- */ private final HashMap states = new HashMap<>(); enum FSM_STATE { @@ -68,7 +70,7 @@ enum FSM_STATE { private String verifierMechanism = null; //RAT Verifier mechanism /* - * The idscp message listener, that should receive the IDSCPv2 messages from the fsm + * The idscp message listener, that should receive the IDSCP2 messages from the fsm * And a listener latch to ensure that the listener is available and the message does not get * lost */ @@ -205,7 +207,7 @@ private void checkForFsmCircles() { } /* - * Get a new IDSCPv2 Message from the secure channel and provide it as an event to the fsm + * Get a new IDSCP2 Message from the secure channel and provide it as an event to the fsm * * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect * driver implementations @@ -286,7 +288,7 @@ public void onRatProverMessage(InternalControlMessage controlMessage, byte[] rat if (ratMessage == null){ e = new Event(controlMessage); } else { - IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpRatProverMessage(ratMessage); + IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpRatProverMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -324,7 +326,7 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] r if (ratMessage == null){ e = new Event(controlMessage); } else { - IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpRatVerifierMessage(ratMessage); + IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpRatVerifierMessage(ratMessage); e = new Event(controlMessage, idscpMessage); } @@ -370,12 +372,12 @@ public void terminate(){ } /* - * API for the user to start the IDSCPv2 handshake + * API for the user to start the IDSCP2 handshake * * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect * driver implementations */ - public void startIdscpHandshake() throws IDSCPv2Exception { + public void startIdscpHandshake() throws Idscp2Exception { //check for incorrect usage checkForFsmCircles(); @@ -384,7 +386,7 @@ public void startIdscpHandshake() throws IDSCPv2Exception { try { if (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { if (fsmIsClosed) { - throw new IDSCPv2Exception("FSM is in a final closed state forever"); + throw new Idscp2Exception("FSM is in a final closed state forever"); } //trigger handshake init @@ -397,14 +399,14 @@ public void startIdscpHandshake() throws IDSCPv2Exception { if (!isConnected()){ //handshake failed, throw exception - throw new IDSCPv2Exception("Handshake failed"); + throw new Idscp2Exception("Handshake failed"); } } else { - throw new IDSCPv2Exception("Handshake has already been started"); + throw new Idscp2Exception("Handshake has already been started"); } } catch (InterruptedException e) { - throw new IDSCPv2Exception("Handshake failed because thread was interrupted"); + throw new Idscp2Exception("Handshake failed because thread was interrupted"); } finally { fsmIsBusy.unlock(); } @@ -456,7 +458,7 @@ public void send(String type, byte[] msg){ fsmIsBusy.lock(); try{ if(isConnected()){ - IdscpMessage idscpMessage = IdscpMessageFactory.createIdscpDataMessage(type, msg); + IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpDataMessage(type, msg); if (!secureChannel.send(idscpMessage.toByteArray())) { LOG.error("Cannot send IDSCP_DATA via secure channel"); onControlMessage(InternalControlMessage.ERROR); @@ -477,7 +479,7 @@ public boolean isConnected(){ } /* - * Register an IDSCPv2 message listener + * Register an IDSCP2 message listener */ public void registerConnection(Idscp2Connection connection){ this.connection = connection; @@ -523,6 +525,7 @@ String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSu * * return false if no match was found */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") boolean restartRatVerifierDriver(){ //assume verifier mechanism is set stopRatVerifierDriver(); @@ -557,6 +560,7 @@ void stopRatVerifierDriver() { * * return false if no match was found */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") boolean restartRatProverDriver(){ //assume prover mechanism is set stopRatProverDriver(); @@ -614,7 +618,7 @@ void shutdownFsm() { } /* - * Provide IDSCPv2 message to the message listener + * Provide IDSCP2 message to the message listener */ void notifyIdscpMsgListener(String type, byte[] data) { try { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index 19639b14e..3b2b322c8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -1,17 +1,15 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; -import de.fhg.aisec.ids.messages.IDSCPv2.*; - /** * An FSM Listener Interface implemented by the FSM to restrict FSM API to the drivers and the - * secure channel class of the IDSCPv2 + * secure channel class of the IDSCP2 * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public interface FsmListener { /* - * A method for providing IDSCPv2 data from the secure channel to the FSM + * A method for providing IDSCP2 data from the secure channel to the FSM */ void onMessage(byte[] data); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index fc62ecdf2..d569e8ba9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; /** - * An enum that wraps the internal control messages of the IDSCPv2 protocol to trigger transitions + * An enum that wraps the internal control messages of the IDSCP2 protocol to trigger transitions * by non-idscpv2-message-events * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 79f5b1e26..412b84c59 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -12,7 +12,7 @@ */ public class State { - private ConcurrentHashMap transitions = new ConcurrentHashMap<>(); + private final ConcurrentHashMap transitions = new ConcurrentHashMap<>(); private Function noTransitionHandler = null; /* diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 919ca4aaa..8b5c0f5fb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -2,16 +2,16 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.locks.Condition; /** - * The Closed State of the FSM of the IDSCPv2 protocol. + * The Closed State of the FSM of the IDSCP2 protocol. * The FSM is in the Closed state either before any transition was triggered (in this case, the * Closed State is the FSM Start state) or after the connection was closed (in this case, the * Closed State is the FSM final state without any outgoing transitions) @@ -44,7 +44,7 @@ public StateClosed(FSM fsm, byte[] dat = dapsDriver.getToken(); LOG.debug("Send IDSCP_HELLO"); - IDSCPv2.IdscpMessage idscpHello = IdscpMessageFactory. + IDSCP2.IdscpMessage idscpHello = Idscp2MessageHelper. createIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); if (!fsm.sendFromFSM(idscpHello)) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index 055e9cd09..4e9a865bc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -1,15 +1,15 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Established State of the FSM of the IDSCPv2 protocol. - * Allows message exchange over the IDSCPv2 protocol between two connectors + * The Established State of the FSM of the IDSCP2 protocol. + * Allows message exchange over the IDSCP2 protocol between two connectors * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -46,8 +46,8 @@ public StateEstablished(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -57,7 +57,7 @@ public StateEstablished(FSM fsm, LOG.debug("Request RAT repeat. Send IDSCP_RERAT, start RAT_VERIFIER"); ratTimer.cancelTimeout(); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpReRatMessage(""))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpReRatMessage(""))) { LOG.error("Cannot send ReRat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -75,7 +75,7 @@ public StateEstablished(FSM fsm, event -> { ratTimer.cancelTimeout(); LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -87,7 +87,7 @@ public StateEstablished(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); @@ -100,11 +100,11 @@ public StateEstablished(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("DAT expired. Send new DAT and repeat RAT"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send Dat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -118,15 +118,15 @@ public StateEstablished(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATA_FIELD_NUMBER, new Transition( event -> { - IDSCPv2.IdscpData data = event.getIdscpMessage().getIdscpData(); + IDSCP2.IdscpData data = event.getIdscpMessage().getIdscpData(); fsm.notifyIdscpMsgListener(data.getType(), data.getData().toByteArray()); return this; } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Receive IDSCP_CLOSED"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 029bce545..8d4b688c4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Dat_And_Rat State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Dat_And_Rat State of the FSM of the IDSCP2 protocol. * Waits for a new valid dynamic attribute token from the peer as well as for the RatProver and * RatVerifier to decide whether the connection will be established or not * @@ -44,8 +44,8 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -60,8 +60,8 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", - IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake timeout", + IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -78,8 +78,8 @@ public StateWaitForDatAndRat(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", - IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("RAT_PROVER failed", + IDSCP2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -95,14 +95,14 @@ public StateWaitForDatAndRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( event -> { handshakeTimer.cancelTimeout(); LOG.debug("Verify received DAT"); @@ -111,8 +111,8 @@ public StateWaitForDatAndRat(FSM fsm, long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage( - "No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage( + "No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -128,11 +128,11 @@ public StateWaitForDatAndRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send Dat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -146,7 +146,7 @@ public StateWaitForDatAndRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); @@ -156,7 +156,7 @@ public StateWaitForDatAndRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); if (!fsm.restartRatProverDriver()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 26aa49d24..80ae6af9a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Dat_And_Rat_Verifier State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Dat_And_Rat_Verifier State of the FSM of the IDSCP2 protocol. * Wait for a new dynamic attribute token from the peer, since the old one is not valid anymore * and waits for the RatVerifier after successful verification of the Dat to decide if the idscpv2 * connection will be established @@ -39,8 +39,8 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -55,20 +55,20 @@ public StateWaitForDatAndRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", - IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake timeout", + IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDAT_FIELD_NUMBER, new Transition( event -> { handshakeTimer.cancelTimeout(); LOG.debug("Verify received DAT"); @@ -77,7 +77,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, long datValidityPeriod; if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No valid DAT", IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } LOG.debug("Remote DAT is valid. Set dat timeout"); @@ -92,11 +92,11 @@ public StateWaitForDatAndRatVerifier(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -109,7 +109,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); if (!fsm.restartRatProverDriver()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index 9ef0669b0..cbfec036e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Hello State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Hello State of the FSM of the IDSCP2 protocol. * Waits for the Idscpv2 Hellp Message that contains the protocol version, the supported and * expected remote attestation cipher suites and the dynamic attribute token (DAT) of the peer. * @@ -53,8 +53,8 @@ public StateWaitForHello(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Received stop signal from user. Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -62,33 +62,33 @@ public StateWaitForHello(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("STATE_WAIT_FOR_HELLO timeout. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake Timeout", - IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake Timeout", + IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPHELLO_FIELD_NUMBER, new Transition( event -> { handshakeTimer.cancelTimeout(); LOG.debug("Received IDSCP_HELLO"); - IDSCPv2.IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); + IDSCP2.IdscpHello idscpHello = event.getIdscpMessage().getIdscpHello(); LOG.debug("Calculate Rat mechanisms"); String proverMechanism = fsm.getRatProverMechanism(localSupportedRatSuite, idscpHello.getExpectedRatSuiteList().toArray()); if (proverMechanism == null){ LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No match for RAT Prover mechanism", - IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No match for RAT Prover mechanism", + IDSCP2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -96,20 +96,19 @@ public StateWaitForHello(FSM fsm, idscpHello.getSupportedRatSuiteList().toArray()); if (verifierMechanism == null){ LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No match for RAT Verifier mechanism", - IDSCPv2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No match for RAT Verifier mechanism", + IDSCP2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } LOG.debug("Verify received DAT"); //check if Dat is available and verify dat - byte[] dat; long datValidityPeriod; if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver - .verifyToken(dat = idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ + .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("No valid DAT", - IDSCPv2.IdscpClose.CloseCause.NO_VALID_DAT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No valid DAT", + IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index a8d4be723..ff05c3c1d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Rat State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Rat State of the FSM of the IDSCP2 protocol. * Waits for the RatProver and RatVerifier Result to decide whether the connection will be * established * @@ -55,8 +55,8 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -82,8 +82,8 @@ public StateWaitForRat(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", - IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("RAT_PROVER failed", + IDSCP2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -92,8 +92,8 @@ public StateWaitForRat(FSM fsm, event -> { LOG.error("RAT_VERIFIER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_VERIFIER failed", - IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("RAT_VERIFIER failed", + IDSCP2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -129,7 +129,7 @@ public StateWaitForRat(FSM fsm, LOG.debug("DAT timeout, send IDSCP_DAT_EXPIRED and cancel RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -144,13 +144,13 @@ public StateWaitForRat(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", - IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake timeout", + IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); @@ -161,7 +161,7 @@ public StateWaitForRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); assert event.getIdscpMessage().hasIdscpRatProver(); @@ -172,11 +172,11 @@ public StateWaitForRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -190,7 +190,7 @@ public StateWaitForRat(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index 4ca9a9443..9978c65ee 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Rat_Prover State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Rat_Prover State of the FSM of the IDSCP2 protocol. * Waits only for the RatProver Result to decide whether the connection will be established * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -43,7 +43,7 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -58,8 +58,8 @@ public StateWaitForRatProver(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", - IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake timeout", + IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -69,7 +69,7 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED"); ratTimer.cancelTimeout(); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -93,8 +93,8 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.error("RAT_PROVER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_PROVER failed", - IDSCPv2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("RAT_PROVER failed", + IDSCP2.IdscpClose.CloseCause.RAT_PROVER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -116,7 +116,7 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpReRatMessage(""))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpReRatMessage(""))) { LOG.error("Cannot send ReRat message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -132,18 +132,18 @@ public StateWaitForRatProver(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -157,7 +157,7 @@ public StateWaitForRatProver(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRATVERIFIER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); @@ -168,7 +168,7 @@ public StateWaitForRatProver(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); if (!fsm.restartRatProverDriver()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 0210b1c7d..77b74f9ea 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -1,14 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.idscp_core.IdscpMessageFactory; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCPv2; +import de.fhg.aisec.ids.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The Wait_For_Rat_Verifier State of the FSM of the IDSCPv2 protocol. + * The Wait_For_Rat_Verifier State of the FSM of the IDSCP2 protocol. * Waits only for the RatVerifier Result to decide whether the connection will be established * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -42,8 +42,8 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("User close", - IDSCPv2.IdscpClose.CloseCause.USER_SHUTDOWN)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -58,7 +58,7 @@ public StateWaitForRatVerifier(FSM fsm, this.addTransition(InternalControlMessage.TIMEOUT.getValue(), new Transition( event -> { LOG.debug("Handshake timeout occurred. Send IDSCP_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("Handshake timeout", IDSCPv2.IdscpClose.CloseCause.TIMEOUT)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("Handshake timeout", IDSCP2.IdscpClose.CloseCause.TIMEOUT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -68,7 +68,7 @@ public StateWaitForRatVerifier(FSM fsm, LOG.debug("DAT timeout occurred. Send IDSCP_DAT_EXPIRED and stop RAT_VERIFIER"); fsm.stopRatVerifierDriver(); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatExpiredMessage())) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { LOG.error("Cannot send DatExpired message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -94,8 +94,8 @@ public StateWaitForRatVerifier(FSM fsm, event -> { LOG.error("RAT_VERIFIER failed"); LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(IdscpMessageFactory.createIdscpCloseMessage("RAT_VERIFIER failed", - IDSCPv2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("RAT_VERIFIER failed", + IDSCP2.IdscpClose.CloseCause.RAT_VERIFIER_FAILED)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); @@ -113,18 +113,18 @@ public StateWaitForRatVerifier(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPCLOSE_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_CLOSE"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPDATEXPIRED_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); - if (!fsm.sendFromFSM(IdscpMessageFactory.createIdscpDatMessage(dapsDriver.getToken()))) { + if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { LOG.error("Cannot send DAT message"); return fsm.getState(FSM_STATE.STATE_CLOSED); } @@ -138,7 +138,7 @@ public StateWaitForRatVerifier(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRATPROVER_FIELD_NUMBER, new Transition( event -> { LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); assert event.getIdscpMessage().hasIdscpRatProver(); @@ -148,7 +148,7 @@ public StateWaitForRatVerifier(FSM fsm, } )); - this.addTransition(IDSCPv2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( + this.addTransition(IDSCP2.IdscpMessage.IDSCPRERAT_FIELD_NUMBER, new Transition( event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); if (!fsm.restartRatProverDriver()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index 253f75cf5..dd01ca635 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -12,7 +12,7 @@ public class TimerThread extends Thread{ private volatile boolean canceled = false; - private long delay; //timeout delay in seconds + private final long delay; //timeout delay in seconds private final Runnable timeoutHandler; //timeout handler routine private final ReentrantLock fsmIsBusy; //lock for the fsm diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java index 3a38ed6d2..3ab864f57 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java @@ -9,7 +9,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ class Transition { - private Function eventHandler; + private final Function eventHandler; Transition(Function eventHandler){ this.eventHandler = eventHandler; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java deleted file mode 100644 index 049df87ab..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IDSCPv2Server.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; - -import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; - -/** - * An IDSCPv2 Server that has the control about the underlying secure server and caches all active - * connections that belong to the secure server - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public class IDSCPv2Server implements IdscpServerListener { - private static final Logger LOG = LoggerFactory.getLogger(IDSCPv2Server.class); - - private SecureServer secureServer; //no race conditions using CountDownLatch - private final CountDownLatch secureServerLatch = new CountDownLatch(1); - private final ConcurrentHashMap connections = new ConcurrentHashMap<>(); - - public IDSCPv2Server() {} - - /* - * Terminate the IDSCPv2 server, the secure server and close all connections - */ - public void terminate(){ - LOG.info("Terminating idscp server {}", this.toString()); - try { - secureServerLatch.await(); - secureServer.safeStop(); - terminateAllSessions(); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } - } - - /* - * Close all open IDSCPv2 connections of this server - */ - public void terminateAllSessions(){ - for (Idscp2Connection c : connections.values()){ - c.close(); - LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); - connections.remove(c.getConnectionId()); - } - } - - /* - * Check if the server is running - */ - public boolean isRunning(){ - try { - secureServerLatch.await(); - return secureServer.isRunning(); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } - return false; - } - - /* - * Get a Idscp2Connection from the server cache by the connectionID - * - * return null if no connection was found with this ID - */ - public Idscp2Connection getConnectionById(String connectionId){ - return connections.get(connectionId); - } - - /* - * return a list of all open IDSCPv2 connections of this server - */ - public Collection getAllConnections(){ - return Collections.unmodifiableCollection(connections.values()); - } - - @Override - public void onConnect(Idscp2Connection connection) { - LOG.debug("Binding new idscpv2 connection to server {}", this.toString()); - connections.put(connection.getConnectionId(), connection); - } - - @Override - public void onClose(String connectionId) { - LOG.debug("Removing connection with id {} from server storage", connectionId); - connections.remove(connectionId); - } - - /* - * Set the corresponding secure server - */ - public void setSecureServer(SecureServer secureServer) { - this.secureServer = secureServer; - secureServerLatch.countDown(); - } -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java new file mode 100644 index 000000000..80bc672ac --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java @@ -0,0 +1,73 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An IDSCP2 Server that has the control about the underlying secure server and caches all active + * connections that belong to the secure server + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class Idscp2Server { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2Server.class); + + private final SecureServer secureServer; + private final ConcurrentHashMap connections = new ConcurrentHashMap<>(); + + public Idscp2Server(SecureServer secureServer, CompletableFuture connectionPromise) { + this.secureServer = secureServer; + connectionPromise.thenAccept(connection -> connections.put(connection.getConnectionId(), connection)); + } + + /* + * Terminate the IDSCP2 server, the secure server and close all connections + */ + public void terminate(){ + LOG.info("Terminating idscp server {}", this.toString()); + secureServer.safeStop(); + terminateAllSessions(); + } + + /* + * Close all open IDSCP2 connections of this server + */ + public void terminateAllSessions(){ + for (Idscp2Connection c : connections.values()){ + c.close(); + LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); + connections.remove(c.getConnectionId()); + } + } + + /* + * Check if the server is running + */ + public boolean isRunning(){ + return secureServer.isRunning(); + } + + /* + * Get a Idscp2Connection from the server cache by the connectionID + * + * return null if no connection was found with this ID + */ + public Idscp2Connection getConnectionById(String connectionId){ + return connections.get(connectionId); + } + + /* + * return a list of all open IDSCP2 connections of this server + */ + public Collection getAllConnections(){ + return Collections.unmodifiableCollection(connections.values()); + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java deleted file mode 100644 index d0600a977..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/IdscpServerListener.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; - -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; - -/** - * An IDSCP Connection Listener interface that is implemented by the IDSCPv2 Server to notify the - * server about lifetimes of IDSCP connections. The server caches all active connections. - */ -public interface IdscpServerListener { - - /* - * Notify the server that a new connection was established - */ - void onConnect(Idscp2Connection connection); - - /* - * Notify the server that connection has been closed - */ - void onClose(String connectionId); -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java index 071d344b2..552307aca 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -17,7 +17,7 @@ */ public class RatProverDriverRegistry { private static RatProverDriverRegistry instance; - private static ConcurrentHashMap drivers = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap drivers = new ConcurrentHashMap<>(); private RatProverDriverRegistry(){} @@ -82,8 +82,8 @@ public void unregisterDriver(String instance){ * An inner static wrapper class, that wraps driver config and driver class */ private static class DriverWrapper { - private Class driverClass; - private Object driverConfig; + private final Class driverClass; + private final Object driverConfig; private DriverWrapper( Class driverClass, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java index accdb9ca9..9d4cbbb82 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java @@ -17,7 +17,7 @@ */ public class RatVerifierDriverRegistry { private static RatVerifierDriverRegistry instance; - private static ConcurrentHashMap drivers + private static final ConcurrentHashMap drivers = new ConcurrentHashMap<>(); private RatVerifierDriverRegistry(){} @@ -78,8 +78,8 @@ public void unregisterDriver(String instance){ * An inner static wrapper class, that wraps driver config and driver class */ private static class DriverWrapper { - private Class driverClass; - private Object driverConfig; + private final Class driverClass; + private final Object driverConfig; private DriverWrapper( Class driver, diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index 4649d7fdb..ff409ea7f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -3,10 +3,11 @@ import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FsmListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.util.concurrent.CountDownLatch; /** - * A secureChannel which is the secure underlying basis of the IDSCPv2 protocol, + * A secureChannel which is the secure underlying basis of the IDSCP2 protocol, * that implements a secureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -14,8 +15,8 @@ public class SecureChannel implements SecureChannelListener { private static final Logger LOG = LoggerFactory.getLogger(SecureChannel.class); - private SecureChannelEndpoint endpoint; - private CountDownLatch fsmLatch = new CountDownLatch(1); + private final SecureChannelEndpoint endpoint; + private final CountDownLatch fsmLatch = new CountDownLatch(1); private FsmListener fsm = null; public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ diff --git a/idscp2/src/main/proto/idscpv2.proto b/idscp2/src/main/proto/idscpv2.proto index 0ca28a5c7..196503c04 100644 --- a/idscp2/src/main/proto/idscpv2.proto +++ b/idscp2/src/main/proto/idscpv2.proto @@ -1,6 +1,6 @@ syntax = "proto3"; option java_package = "de.fhg.aisec.ids.messages"; -option java_outer_classname = "IDSCPv2"; +option java_outer_classname = "IDSCP2"; //IDSCP message frame message IdscpMessage { From 24ff3672a3ed92af6a8da4dd5208296de95f8a8b Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 20 May 2020 18:33:40 +0200 Subject: [PATCH 073/237] Added focal version of protobuf-compiler to build container --- docker-build/Dockerfile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docker-build/Dockerfile b/docker-build/Dockerfile index 549fbb8ca..fcac1a70d 100644 --- a/docker-build/Dockerfile +++ b/docker-build/Dockerfile @@ -10,9 +10,13 @@ RUN wget -O - https://deb.nodesource.com/setup_12.x | bash - && apt-get install # Install yarn RUN wget -O - https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ - && apt-get update && apt-get install yarn -# Install protobuf compiler (protoc) -RUN apt-get update -qq && apt-get install -qq protobuf-compiler + && apt-get update -qq && apt-get -qq install yarn +# Install newer protobuf compiler from focal (3.0.x doesn't generate required has...() methods) +# This is an ugly hack, but maintains compatiblity to non-x86 platforms +RUN sed -e 's/bionic/focal/' /etc/apt/sources.list > /etc/apt/sources.list.d/focal.list \ + && apt-get update -qq && apt-get install -qq protobuf-compiler \ + # Perform cleanup + && rm /etc/apt/sources.list.d/focal.list && apt-get clean && rm -r /var/lib/apt/lists/* COPY run.sh . RUN chmod +x run.sh From c1d1844c87b8a49dd2fad3632e8042254a6abae0 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 20 May 2020 19:16:48 +0200 Subject: [PATCH 074/237] Minimal supplement of Idscp2MessageListener --- .../fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java | 4 ++-- .../fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java | 6 +++--- .../fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java | 4 ++-- .../aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index b3a0d4f6f..ecf410568 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -77,10 +77,10 @@ public void onClose(String connectionId) { System.out.println("Client: Connection with id " + connectionId + " has been closed"); } }); - connection.addGenericMessageListener(((type, data) -> System.out.println( + connection.addGenericMessageListener(((c, type, data) -> System.out.println( "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); // Register listener for server reply - connection.addMessageListener("pong", (type, data) -> + connection.addMessageListener("pong", (c, type, data) -> System.out.println("Received pong message: " + new String(data, StandardCharsets.UTF_8))); System.out.println("Sending PING..."); connection.send("ping", "PING".getBytes(StandardCharsets.UTF_8)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index ff89f928f..a5d79ce94 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -93,12 +93,12 @@ public void onClose(String connectionId) { System.out.println("Server: Connection with id " + connectionId + " has been closed"); } }); - connection.addGenericMessageListener(((type, data) -> System.out.println( + connection.addGenericMessageListener(((c, type, data) -> System.out.println( "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); - connection.addMessageListener("ping", ((type, data) -> { + connection.addMessageListener("ping", ((c, type, data) -> { System.out.println("Received ping message:\n" + new String(data, StandardCharsets.UTF_8)); System.out.println("Sending PONG..."); - connection.send("pong", "PONG".getBytes(StandardCharsets.UTF_8)); + c.send("pong", "PONG".getBytes(StandardCharsets.UTF_8)); })); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index e5e7cea90..0546b40c6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -49,13 +49,13 @@ public void send(String type, byte[] msg) { public void onMessage(String type, byte[] msg) { LOG.debug("Received new IDSCP Message: " + Arrays.toString(msg)); synchronized (genericMessageListeners) { - genericMessageListeners.forEach(l -> l.onMessage(type, msg)); + genericMessageListeners.forEach(l -> l.onMessage(this, type, msg)); } Set listeners = messageListeners.get(type); if (listeners != null) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (listeners) { - listeners.forEach(l -> l.onMessage(type, msg)); + listeners.forEach(l -> l.onMessage(this, type, msg)); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java index 5576deac1..45853f638 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageListener.java @@ -8,5 +8,5 @@ public interface Idscp2MessageListener { /* * notify the listener about new data */ - void onMessage(String type, byte[] data); + void onMessage(Idscp2Connection connection, String type, byte[] data); } From cdc376f9d63edc05133443aa29c3320f2a52d617 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 20 May 2020 23:56:30 +0200 Subject: [PATCH 075/237] Initial server implementation (WIP) --- camel-idscp2/LICENSE.txt | 201 ++++++++++++++++++ camel-idscp2/README.md | 1 + camel-idscp2/bnd.bnd | 11 + camel-idscp2/build.gradle | 22 ++ .../ids/camel/idscp2/Idscp2OsgiComponent.java | 123 +++++++++++ .../idscp2/server/Idscp2ServerComponent.java | 57 +++++ .../idscp2/server/Idscp2ServerConsumer.java | 71 +++++++ .../idscp2/server/Idscp2ServerEndpoint.java | 174 +++++++++++++++ .../idscp2/server/Idscp2ServerProducer.java | 42 ++++ .../org/apache/camel/component/idscp2client | 17 ++ .../org/apache/camel/component/idscp2server | 17 ++ 11 files changed, 736 insertions(+) create mode 100644 camel-idscp2/LICENSE.txt create mode 100644 camel-idscp2/README.md create mode 100644 camel-idscp2/bnd.bnd create mode 100644 camel-idscp2/build.gradle create mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java create mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java create mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java create mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java create mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java create mode 100644 camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client create mode 100644 camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server diff --git a/camel-idscp2/LICENSE.txt b/camel-idscp2/LICENSE.txt new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/camel-idscp2/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/camel-idscp2/README.md b/camel-idscp2/README.md new file mode 100644 index 000000000..2c92b5fc9 --- /dev/null +++ b/camel-idscp2/README.md @@ -0,0 +1 @@ +The _camel-idscp2_ module adds IDSCP2 support to the integrated Camel deployment. It creates a Camel Component to make IDSCP2 available for building Camel routes. IDSCP2 itself is contained in module _idscp2_. diff --git a/camel-idscp2/bnd.bnd b/camel-idscp2/bnd.bnd new file mode 100644 index 000000000..5ea70404e --- /dev/null +++ b/camel-idscp2/bnd.bnd @@ -0,0 +1,11 @@ +Bundle-Name: IDS :: Camel IDSCP Support +Bundle-Description: Camel IDS protocol support +Export-Package: de.fhg.camel.ids.server,\ + de.fhg.camel.ids.connectionmanagement,\ + de.fhg.camel.ids.client +Import-Package: \ + !org.checkerframework.checker.*,\ + * +DynamicImport-Package: \ + org.asynchttpclient.netty.*,\ + com.typesafe.netty.* diff --git a/camel-idscp2/build.gradle b/camel-idscp2/build.gradle new file mode 100644 index 000000000..ad2d9c165 --- /dev/null +++ b/camel-idscp2/build.gradle @@ -0,0 +1,22 @@ +description = 'Camel IDS Component' + +dependencies { + providedByBundle(project(':ids-api')) { transitive = false } + providedByBundle(project(':idscp2')) { transitive = false } + + // Bill of Materials (BOM) for Camel + bom group: 'org.apache.camel', name: 'camel-parent', version: libraryVersions.camel + + providedByFeature group: 'org.apache.camel', name: 'camel-core', version: libraryVersions.camel + + compileOnly group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual + + osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium + osgiCore group: 'org.osgi', name: 'org.osgi.core', version: libraryVersions.osgi + + providedByFeature group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf + + testImplementation group: 'junit', name: 'junit' + testImplementation group: 'org.apache.camel', name: 'camel-test', version: libraryVersions.camel + testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java new file mode 100644 index 000000000..b6f204bcc --- /dev/null +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java @@ -0,0 +1,123 @@ +/*- + * ========================LICENSE_START================================= + * camel-ids + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.camel.idscp2; + +import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; +import de.fhg.aisec.ids.api.infomodel.InfoModel; +import de.fhg.aisec.ids.api.settings.Settings; +import de.fhg.aisec.ids.api.tokenm.TokenManager; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.osgi.service.component.annotations.*; + +@Component +public class Idscp2OsgiComponent { + + @Reference(cardinality = ReferenceCardinality.MANDATORY) + private Settings settings = null; + + @Reference(cardinality = ReferenceCardinality.MANDATORY) + private InfoModel infoModelManager = null; + + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + private TokenManager tokenManager = null; + + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + private EndpointConfigManager endpointConfigManager = null; + + private static Idscp2OsgiComponent instance; + + @Activate + @SuppressWarnings("squid:S2696") + protected void activate() { + instance = this; + } + + @Deactivate + @SuppressWarnings("squid:S2696") + protected void deactivate() { + instance = null; + } + + @Nullable + public static Settings getSettings() { + Idscp2OsgiComponent in = instance; + if (in != null) { + return in.settings; + } + return null; + } + + /** + * Is actually NonNull due to ReferenceCardinality.MANDATORY, + * but instance might be null for Unit Tests + * @return Info-Model-Manager instance + */ + @Nullable + public static InfoModel getInfoModelManager() { + Idscp2OsgiComponent in = instance; + if (in != null) { + return in.infoModelManager; + } + return null; + } + + /** + * Is actually NonNull due to ReferenceCardinality.MANDATORY, + * but instance might be null for Unit Tests + * @return Token-Manager instance + */ + @Nullable + public static TokenManager getTokenManager() { + Idscp2OsgiComponent in = instance; + if (in != null) { + return in.tokenManager; + } + return null; + } + + @Nullable + public static EndpointConfigManager getEndpointConfigManager() { + Idscp2OsgiComponent in = instance; + if (in != null) { + return in.endpointConfigManager; + } + return null; + } + + public void setSettings(Settings settings) { + this.settings = settings; + } + + public void setInfoModelManager(InfoModel infoModelManager) { + this.infoModelManager = infoModelManager; + } + + public void setTokenManager(TokenManager tokenManager) { + this.tokenManager = tokenManager; + } + + public void setEndpointConfigManager(EndpointConfigManager endpointConfigManager) { + this.endpointConfigManager = endpointConfigManager; + } + + public static void setInstance(Idscp2OsgiComponent instance) { + Idscp2OsgiComponent.instance = instance; + } +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java new file mode 100644 index 000000000..7d88f53ad --- /dev/null +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server; + +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; +import org.apache.camel.Endpoint; +import org.apache.camel.spi.annotations.Component; +import org.apache.camel.support.DefaultComponent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Component("idscp2server") +public class Idscp2ServerComponent extends DefaultComponent { + static final int DEFAULT_PORT = 29292; + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerComponent.class); + + final Map servers = new ConcurrentHashMap<>(); + + public Idscp2ServerComponent() { + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { + Endpoint endpoint = new Idscp2ServerEndpoint(uri, remaining, this); + setProperties(endpoint, parameters); + return endpoint; + } + + public synchronized void addServer(int port, Idscp2Server server) { + servers.put(port, server); + } + + @Override + protected synchronized void doStop() throws Exception { + for (Idscp2Server s : servers.values()) { + s.terminate(); + } + super.doStop(); + } +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java new file mode 100644 index 000000000..ce5706cf2 --- /dev/null +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server; + +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.support.DefaultConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The IDSCP2 server consumer. + */ +public class Idscp2ServerConsumer extends DefaultConsumer implements Idscp2MessageListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerConsumer.class); + private final Idscp2ServerEndpoint endpoint; + + public Idscp2ServerConsumer(final Idscp2ServerEndpoint endpoint, final Processor processor) { + super(endpoint, processor); + this.endpoint = endpoint; + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + endpoint.addConsumer(this); + } + + @Override + protected void doStop() throws Exception { + endpoint.removeConsumer(this); + super.doStop(); + } + + @Override + public void onMessage(Idscp2Connection connection, String type, byte[] data) { + final var exchange = endpoint.createExchange(); + try { + this.createUoW(exchange); + // Set relevant information + exchange.getIn().setHeader("idscp2.type", type); + exchange.getIn().setBody(data, byte[].class); + // Do processing + getProcessor().process(exchange); + // Handle response + Message response = exchange.getMessage(); + String responseType = response.getHeader("idscp2.type", String.class); + connection.send(responseType, response.getBody(byte[].class)); + } catch (Exception e) { + LOG.error("Error in Idscp2ServerConsumer.onMessage()", e); + } finally { + this.doneUoW(exchange); + } + } +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java new file mode 100644 index 000000000..b82150b7f --- /dev/null +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server; + +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; +import de.fhg.aisec.ids.idscp2.example.RunTLSClient; +import de.fhg.aisec.ids.idscp2.example.RunTLSServer; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.support.DefaultEndpoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +@UriEndpoint( + scheme = "idscp2server", + title = "IDSCP2 Server Socket", + syntax = "idscp2server://host:port", + label = "ids" +) +public class Idscp2ServerEndpoint extends DefaultEndpoint implements Idscp2EndpointListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerEndpoint.class); + private static final Pattern URI_REGEX = Pattern.compile("(.*?):(\\d+)$"); + + private final Idscp2Configuration serverConfiguration; + private final Idscp2Settings serverSettings; + private Idscp2Server server; + private final Set consumers = new HashSet<>(); + + public Idscp2ServerEndpoint(String uri, String remaining, Idscp2ServerComponent component) { + super(uri, component); + final var uriMatcher = URI_REGEX.matcher(remaining); + if (!uriMatcher.matches()) { + throw new IllegalArgumentException(remaining + " is not a valid URI."); + } + final var matchResult = uriMatcher.toMatchResult(); + final var host = matchResult.group(1); + final var port = Integer.parseInt(matchResult.group(2)); + + SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + + serverSettings = new Idscp2Settings.Builder() + .setHost(host) + .setServerPort(port) + .setKeyStore(RunTLSClient.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStore(RunTLSServer.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") + .setRatTimeoutDelay(14) + .build(); + + DefaultDapsDriverConfig config = + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(serverSettings.getKeyStorePath()) + .setTrustStorePath(serverSettings.getTrustStorePath()) + .setKeyStorePassword(serverSettings.getKeyStorePassword()) + .setTrustStorePassword(serverSettings.getTrustStorePassword()) + .setKeyAlias(serverSettings.getDapsKeyAlias()) + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); + DapsDriver dapsDriver = new DefaultDapsDriver(config); + + RatProverDriverRegistry.getInstance().registerDriver( + "Dummy", RatProverDummy.class, null); + RatVerifierDriverRegistry.getInstance().registerDriver( + "Dummy", RatVerifierDummy.class, null); + RatProverDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dProver.class, + new TPM2dProverConfig.Builder().build() + ); + RatVerifierDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dVerifier.class, + new TPM2dVerifierConfig.Builder().build() + ); + + serverConfiguration = new Idscp2Configuration( + this, + dapsDriver, + secureChannelDriver, + serverSettings.getExpectedAttestation(), + serverSettings.getSupportedAttestation(), + serverSettings.getRatTimeoutDelay() + ); + } + + public synchronized void addConsumer(Idscp2ServerConsumer consumer) { + this.consumers.add(consumer); + this.server.getAllConnections().forEach(c -> c.addGenericMessageListener(consumer)); + } + + public synchronized void removeConsumer(Idscp2ServerConsumer consumer) { + this.consumers.remove(consumer); + this.server.getAllConnections().forEach(c -> c.removeGenericMessageListener(consumer)); + } + + public synchronized void sendMessage(String type, byte[] body) { + this.server.getAllConnections().forEach(connection -> connection.send(type, body)); + } + + @Override + public synchronized Producer createProducer() { + return new Idscp2ServerProducer(this); + } + + @Override + public synchronized Consumer createConsumer(Processor processor) { + return new Idscp2ServerConsumer(this, processor); + } + + @Override + public synchronized void onConnection(Idscp2Connection connection) { + LOG.debug("New IDSCP2 connection on " + getEndpointUri() + ", register consumer listeners"); + this.consumers.forEach(connection::addGenericMessageListener); + } + + @Override + public void onError(String error) { + LOG.error("Error in IDSCP2 server endpoint " + getEndpointUri() + ":\n" + error); + } + + @Override + public synchronized void doStart() throws Idscp2Exception { + LOG.debug("Starting IDSCP2 server endpoint " + getEndpointUri()); + this.server = serverConfiguration.listen(serverSettings); + ((Idscp2ServerComponent) this.getComponent()).addServer(this.serverSettings.getServerPort(), this.server); + } + + @Override + public synchronized void doStop() { + LOG.debug("Stopping IDSCP2 server endpoint " + getEndpointUri()); + this.server.terminate(); + } + +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java new file mode 100644 index 000000000..579279079 --- /dev/null +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server; + +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.support.DefaultProducer; + +/** + * The IDSCP2 server producer. + * Sends each message to all clients connected to this server endpoint. + */ +public class Idscp2ServerProducer extends DefaultProducer { + private final Idscp2ServerEndpoint endpoint; + + public Idscp2ServerProducer(Idscp2ServerEndpoint endpoint) { + super(endpoint); + this.endpoint = endpoint; + } + + @Override + public void process(Exchange exchange) { + Message message = exchange.getIn(); + String type = message.getHeader("idscp.type", String.class); + byte[] body = message.getBody(byte[].class); + endpoint.sendMessage(type, body); + } +} diff --git a/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client new file mode 100644 index 000000000..57aaa95c7 --- /dev/null +++ b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class=de.fhg.aisec.ids.camel.idscp2.client.WsComponent diff --git a/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server new file mode 100644 index 000000000..95abf4615 --- /dev/null +++ b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2server @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class=de.fhg.aisec.ids.camel.idscp2.server.Idscp2ServerComponent From cab29be33cb4b6a23ef0c0d78aa603352d7781d3 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 21 May 2020 17:11:09 +0200 Subject: [PATCH 076/237] Small cleanups --- .../camel/idscp2/server/Idscp2ServerComponent.java | 5 ----- .../configuration/Idscp2Configuration.java | 12 ++++++------ settings.gradle | 1 + 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java index 7d88f53ad..5a7375185 100644 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java @@ -20,17 +20,12 @@ import org.apache.camel.Endpoint; import org.apache.camel.spi.annotations.Component; import org.apache.camel.support.DefaultComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component("idscp2server") public class Idscp2ServerComponent extends DefaultComponent { - static final int DEFAULT_PORT = 29292; - private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerComponent.class); - final Map servers = new ConcurrentHashMap<>(); public Idscp2ServerComponent() { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java index 3ca887848..64890880f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java @@ -23,7 +23,7 @@ public class Idscp2Configuration implements Idscp2Callback { private static final Logger LOG = LoggerFactory.getLogger(Idscp2Configuration.class); - private final Idscp2EndpointListener user; + private final Idscp2EndpointListener endpointListener; private final DapsDriver dapsDriver; private final SecureChannelDriver secureChannelDriver; private final String[] localExpectedRatCipher; @@ -31,14 +31,14 @@ public class Idscp2Configuration implements Idscp2Callback { private final int ratTimeout; - public Idscp2Configuration(Idscp2EndpointListener initiator, + public Idscp2Configuration(Idscp2EndpointListener endpointListener, DapsDriver dapsDriver, SecureChannelDriver secureChannelDriver, AttestationConfig expectedAttestation, AttestationConfig supportedAttestation, int ratTimeout ){ - this.user = initiator; + this.endpointListener = endpointListener; this.dapsDriver = dapsDriver; this.secureChannelDriver = secureChannelDriver; this.localExpectedRatCipher = expectedAttestation.getRatMechanisms(); @@ -86,7 +86,7 @@ public Idscp2Server listen(Idscp2Settings settings) throws Idscp2Exception { public void secureChannelConnectHandler(SecureChannel secureChannel) { if (secureChannel == null){ LOG.warn("IDSCP2 connect failed because no secure channel was established"); - user.onError("IDSCP2 connect failed because no secure channel was established"); + endpointListener.onError("IDSCP2 connect failed because no secure channel was established"); } else { LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, @@ -102,7 +102,7 @@ public void secureChannelConnectHandler(SecureChannel secureChannel) { Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); fsm.registerConnection(newConnection); LOG.info("A new IDSCP2 connection with id {} was created", connectionId); - user.onConnection(newConnection); + endpointListener.onConnection(newConnection); } } @@ -137,7 +137,7 @@ public void secureChannelListenHandler(SecureChannel secureChannel, LOG.info("A new idscpv2 connection with id {} was created", connectionId); // Complete the connection promise for the IDSCP server connectionPromise.complete(newConnection); - user.onConnection(newConnection); + endpointListener.onConnection(newConnection); } else { LOG.warn("An incoming idscpv2 client connection request failed because the secure channel is null."); } diff --git a/settings.gradle b/settings.gradle index 322be4211..ca6f28465 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ rootProject.name = 'trusted-connector-core' include ':camel-ids' +include ':camel-idscp2' include ':camel-influxdb' include ':camel-multipart-processor' include ':cxf-jaxws-patch' From 7a5051329cd9a081af1f0b62e0e4c2250bb7a997 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Sun, 24 May 2020 17:48:18 +0200 Subject: [PATCH 077/237] Implemented JWT wrapper bundle for correct io.jsonwebtoken exports --- jsonwebtoken-wrapper/LICENSE.txt | 201 ++++++++++++++++++++++++++ jsonwebtoken-wrapper/README.md | 1 + jsonwebtoken-wrapper/bnd.bnd | 8 + jsonwebtoken-wrapper/build.gradle.kts | 8 + karaf-assembly/build.gradle | 1 + karaf-features-ids/build.gradle | 2 +- settings.gradle | 1 + 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 jsonwebtoken-wrapper/LICENSE.txt create mode 100644 jsonwebtoken-wrapper/README.md create mode 100644 jsonwebtoken-wrapper/bnd.bnd create mode 100644 jsonwebtoken-wrapper/build.gradle.kts diff --git a/jsonwebtoken-wrapper/LICENSE.txt b/jsonwebtoken-wrapper/LICENSE.txt new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/jsonwebtoken-wrapper/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/jsonwebtoken-wrapper/README.md b/jsonwebtoken-wrapper/README.md new file mode 100644 index 000000000..94bec9404 --- /dev/null +++ b/jsonwebtoken-wrapper/README.md @@ -0,0 +1 @@ +The _jsonwebtoken-wrapper_ module wraps the io.jsonwebsocket package to make it available to the OSGi layer. This is needed for idscp2 and ids-token-manager. diff --git a/jsonwebtoken-wrapper/bnd.bnd b/jsonwebtoken-wrapper/bnd.bnd new file mode 100644 index 000000000..2d384e18d --- /dev/null +++ b/jsonwebtoken-wrapper/bnd.bnd @@ -0,0 +1,8 @@ +Bundle-Name: JWT (JSON web token) Wrapper +Bundle-Description: JWT (JSON web token) Wrapper Bundle +Import-Package: \ + !io.jsonwebtoken*,\ + * +# Merge split-package io.jsonwebtoken +Export-Package: \ + io.jsonwebtoken*;-split-package:=merge-last diff --git a/jsonwebtoken-wrapper/build.gradle.kts b/jsonwebtoken-wrapper/build.gradle.kts new file mode 100644 index 000000000..5cb1bfa31 --- /dev/null +++ b/jsonwebtoken-wrapper/build.gradle.kts @@ -0,0 +1,8 @@ +@Suppress("UNCHECKED_CAST") val libraryVersions = + rootProject.ext.get("libraryVersions") as Map + +dependencies { + providedByBundle("io.jsonwebtoken", "jjwt-impl", libraryVersions["jsonwebtoken"]) + providedByBundle("io.jsonwebtoken", "jjwt-jackson", libraryVersions["jsonwebtoken"]) + providedByBundle("io.jsonwebtoken", "jjwt-api", libraryVersions["jsonwebtoken"]) +} diff --git a/karaf-assembly/build.gradle b/karaf-assembly/build.gradle index 367ce7969..f05178224 100644 --- a/karaf-assembly/build.gradle +++ b/karaf-assembly/build.gradle @@ -54,6 +54,7 @@ task assembleKaraf(type: CrossPlatformExec) { commandLine "./mvnw", "--no-transfer-progress", "clean", "package" } // Sometimes required to fix an error caused by a non-existing folder (maybe caused by mvn clean) +mkdir("${project.buildDir}/classes/kotlin/test") assembleKaraf.doLast { mkdir("${project.buildDir}/classes/kotlin/test") } diff --git a/karaf-features-ids/build.gradle b/karaf-features-ids/build.gradle index 3231dbea3..dd6078524 100644 --- a/karaf-features-ids/build.gradle +++ b/karaf-features-ids/build.gradle @@ -9,7 +9,7 @@ ext { rootProject.configurations.findAll { it.name.endsWith('Bundle') }.each { project.ext.bundleConfigurations.add(it.name) } -rootProject.subprojects.findAll { it.name.matches("(^(camel|ids|jnr)-.*|.*-patch\$)") }.each { p -> +rootProject.subprojects.findAll { it.name.matches("(^(camel|ids)-.*|.*-(patch|wrapper)\$)") }.each { p -> Boolean included = false // Include each sub-project declaring dependencies with a configuration ending on "Bundle", // using exactly that configuration for the dependency itself and selection of additional recursive dependencies. diff --git a/settings.gradle b/settings.gradle index ca6f28465..5e0df3d66 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,6 +21,7 @@ include ':ids-webconsole' include ':idscp2' include ':javax-xml-bind-patch' include ':jnr-unixsocket-wrapper' +include ':jsonwebtoken-wrapper' include ':karaf-assembly' include ':karaf-features-ids' include ':rat-repository' From f19e800dce1272f2e6583cfd526e94ab154f5428 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Sun, 24 May 2020 17:48:45 +0200 Subject: [PATCH 078/237] Changed token manager to use JWT wrapper --- ids-token-manager/bnd.bnd | 6 ++---- ids-token-manager/build.gradle | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ids-token-manager/bnd.bnd b/ids-token-manager/bnd.bnd index eb54369e5..91074f4d8 100755 --- a/ids-token-manager/bnd.bnd +++ b/ids-token-manager/bnd.bnd @@ -1,6 +1,4 @@ Bundle-Name: IDS :: Token Manager Import-Package: \ - !com.android.org.conscrypt,\ - * -Private-Package: \ - io.jsonwebtoken*;-split-package:=merge-last \ No newline at end of file + !com.android.org.conscrypt,\ + * \ No newline at end of file diff --git a/ids-token-manager/build.gradle b/ids-token-manager/build.gradle index 297a6459f..dfcd54352 100755 --- a/ids-token-manager/build.gradle +++ b/ids-token-manager/build.gradle @@ -3,9 +3,9 @@ dependencies { osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken - providedByBundle group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken + implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: libraryVersions.jsonwebtoken + implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: libraryVersions.jsonwebtoken + implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: libraryVersions.jsonwebtoken providedByBundle group: 'com.squareup.okhttp3', name: 'okhttp', version: libraryVersions.okhttp providedByBundle group: 'com.squareup.okio', name: 'okio', version: libraryVersions.okio providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: libraryVersions.jose4j From 152ab3d7268e487e852d39f1e44d46dfe05e832a Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Sun, 24 May 2020 17:53:20 +0200 Subject: [PATCH 079/237] Massive IDSCP2 refactoring, cleanup, bug fixes, example files --- idscp2/build.gradle.kts | 11 +- .../daps/DefaultDapsDriver.java | 101 ++-- .../daps/DefaultDapsDriverConfig.java | 148 +++--- .../daps/SecurityRequirements.java | 41 +- .../CustomX509ExtendedKeyManager.java | 24 +- .../keystores/PreConfiguration.java | 13 +- .../rat/dummy/RatProverDummy.java | 6 +- .../rat/dummy/RatVerifierDummy.java | 6 +- .../rat/tpm2d/TPM2dHelper.java | 117 ++--- .../rat/tpm2d/TPM2dMessageFactory.java | 142 +++--- .../rat/tpm2d/TPM2dProver.java | 374 +++++++------- .../rat/tpm2d/TPM2dProverConfig.java | 57 +-- .../rat/tpm2d/TPM2dSocket.java | 38 +- .../rat/tpm2d/TPM2dVerifier.java | 464 +++++++++--------- .../rat/tpm2d/TPM2dVerifierConfig.java | 96 ++-- .../secure_channel/NativeTLSDriver.java | 45 +- .../secure_channel/TLSConstants.java | 67 +++ .../TLSSessionVerificationHelper.java | 324 ++++++------ .../secure_channel/TlsConstants.java | 117 ----- .../client/DataAvailableListener.java | 2 +- .../client/InputListenerThread.java | 10 +- .../secure_channel/client/TLSClient.java | 105 ++-- .../secure_channel/server/TLSServer.java | 121 +++-- .../server/TLSServerThread.java | 126 ++--- .../drivers/interfaces/RatProverDriver.java | 9 +- .../drivers/interfaces/RatVerifierDriver.java | 7 +- .../interfaces/SecureChannelDriver.java | 11 +- .../ids/idscp2/error/Idscp2Exception.java | 2 +- .../idscp2/example/Idscp2ClientInitiator.java | 71 +-- .../idscp2/example/Idscp2ServerInitiator.java | 84 ++-- .../ids/idscp2/example/RunTLSClient.java | 18 +- .../ids/idscp2/example/RunTLSServer.java | 18 +- .../ids/idscp2/idscp_core/FastLatch.java | 50 ++ .../idscp2/idscp_core/Idscp2Connection.java | 97 ++-- .../idscp_core/Idscp2ConnectionAdapter.java | 12 + .../idscp_core/Idscp2ConnectionListener.java | 2 +- .../idscp_core/Idscp2MessageHelper.java | 24 +- .../configuration/AttestationConfig.java | 6 +- .../configuration/Idscp2Configuration.java | 110 ++--- .../configuration/Idscp2Settings.java | 53 +- ...ck.java => SecureChannelInitListener.java} | 17 +- .../finite_state_machine/Event.java | 21 +- .../idscp_core/finite_state_machine/FSM.java | 128 +++-- .../InternalControlMessage.java | 12 +- .../finite_state_machine/State.java | 15 +- .../finite_state_machine/StateClosed.java | 29 +- .../StateEstablished.java | 34 +- .../StateWaitForDatAndRat.java | 34 +- .../StateWaitForDatAndRatVerifier.java | 26 +- .../StateWaitForHello.java | 24 +- .../finite_state_machine/StateWaitForRat.java | 34 +- .../StateWaitForRatProver.java | 36 +- .../StateWaitForRatVerifier.java | 26 +- .../finite_state_machine/Timer.java | 10 +- .../finite_state_machine/TimerThread.java | 10 +- .../finite_state_machine/Transition.java | 6 +- .../idscp_core/idscp_server/Idscp2Server.java | 51 +- .../ServerConnectionListener.java | 10 + .../rat_registry/RatProverDriverRegistry.java | 29 +- .../RatVerifierDriverRegistry.java | 27 +- .../secure_channel/SecureChannel.java | 47 +- .../secure_channel/SecureChannelEndpoint.java | 2 +- idscp2/src/main/proto/idscpv2.proto | 2 +- idscp2/src/main/proto/tpm2dAttestation.proto | 2 +- .../main/resources/simplelogger.properties | 1 + .../ssl/aisecconnector1-keystore.jks | Bin .../ssl/aisecconnector2-keystore.jks | Bin .../resources/ssl/client-truststore_new.jks | Bin .../resources/ssl/consumer-core-keystore.jks | Bin .../ssl/consumer-core-truststore.jks | Bin .../resources/ssl/consumer-core.cert | 0 .../resources/ssl/consumer-core.p12 | Bin .../resources/ssl/provider-core-keystore.jks | Bin .../ssl/provider-core-truststore.jks | Bin .../resources/ssl/provider-core.cert | 0 .../resources/ssl/provider-core.p12 | Bin idscp2/src/test/java/DapsDriverTest.java | 21 +- .../etc/idscp2/aisecconnector1-keystore.jks | Bin 0 -> 2527 bytes .../etc/idscp2/client-truststore_new.jks | Bin 0 -> 1974 bytes 79 files changed, 1870 insertions(+), 1913 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSConstants.java delete mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/FastLatch.java create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/{Idscp2Callback.java => SecureChannelInitListener.java} (52%) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/ServerConnectionListener.java create mode 100644 idscp2/src/main/resources/simplelogger.properties rename idscp2/src/{test => main}/resources/ssl/aisecconnector1-keystore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/aisecconnector2-keystore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/client-truststore_new.jks (100%) rename idscp2/src/{test => main}/resources/ssl/consumer-core-keystore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/consumer-core-truststore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/consumer-core.cert (100%) rename idscp2/src/{test => main}/resources/ssl/consumer-core.p12 (100%) rename idscp2/src/{test => main}/resources/ssl/provider-core-keystore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/provider-core-truststore.jks (100%) rename idscp2/src/{test => main}/resources/ssl/provider-core.cert (100%) rename idscp2/src/{test => main}/resources/ssl/provider-core.p12 (100%) create mode 100644 karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks create mode 100644 karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.jks diff --git a/idscp2/build.gradle.kts b/idscp2/build.gradle.kts index 249056733..ad98fbd39 100644 --- a/idscp2/build.gradle.kts +++ b/idscp2/build.gradle.kts @@ -1,9 +1,8 @@ import com.google.protobuf.gradle.protobuf import org.gradle.plugins.ide.idea.model.IdeaModel -import org.yaml.snakeyaml.Yaml @Suppress("UNCHECKED_CAST") val libraryVersions = - Yaml().load(File("${rootDir}/libraryVersions.yaml").inputStream()) as Map + rootProject.ext.get("libraryVersions") as Map version = libraryVersions["idscp2"] ?: error("IDSCP2 version not specified") @@ -30,15 +29,17 @@ configure { } dependencies { + providedByBundle(project(":ids-api")) { isTransitive = false } + providedByBundle("com.github.microsoft", "TSS.Java", libraryVersions["tssJava"]) providedByBundle("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) publishCompile("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) - providedByBundle("io.jsonwebtoken", "jjwt-impl", libraryVersions["jsonwebtoken"]) - providedByBundle("io.jsonwebtoken", "jjwt-jackson", libraryVersions["jsonwebtoken"]) - providedByBundle("io.jsonwebtoken", "jjwt-api", libraryVersions["jsonwebtoken"]) + implementation("io.jsonwebtoken", "jjwt-impl", libraryVersions["jsonwebtoken"]) + implementation("io.jsonwebtoken", "jjwt-jackson", libraryVersions["jsonwebtoken"]) + implementation("io.jsonwebtoken", "jjwt-api", libraryVersions["jsonwebtoken"]) providedByBundle("org.json", "json", libraryVersions["orgJson"]) providedByBundle("org.bitbucket.b_c", "jose4j", libraryVersions["jose4j"]) providedByBundle("com.squareup.okhttp3", "okhttp", libraryVersions["okhttp"]) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 3c6279d70..ea830f884 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -39,7 +39,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class DefaultDapsDriver implements DapsDriver { - private static final Logger LOG = LoggerFactory.getLogger(DefaultDapsDriver.class); + private static final Logger LOG = LoggerFactory.getLogger(DefaultDapsDriver.class); private final SSLSocketFactory sslSocketFactory; //ssl socket factory can be reused private final X509ExtendedTrustManager trustManager; //trust manager can be reused @@ -55,14 +55,14 @@ public DefaultDapsDriver(DefaultDapsDriverConfig config) { //create ssl socket factory for secure privateKey = PreConfiguration.getKey( - config.getKeyStorePath(), - config.getKeyStorePassword(), - config.getKeyAlias() + config.getKeyStorePath(), + config.getKeyStorePassword(), + config.getKeyAlias() ); TrustManager[] trustManagers = PreConfiguration.getX509ExtTrustManager( - config.getTrustStorePath(), - config.getTrustStorePassword() + config.getTrustStorePath(), + config.getTrustStorePassword() ); this.trustManager = (X509ExtendedTrustManager) trustManagers[0]; @@ -91,38 +91,38 @@ public byte[] getToken() { //create signed JWT String jwt = - Jwts.builder() - .setIssuer(connectorUUID) - .setSubject(connectorUUID) - .setExpiration(Date.from(Instant.now().plusSeconds(86400))) - .setIssuedAt(Date.from(Instant.now())) - .setNotBefore(Date.from(Instant.now())) - .setAudience(targetAudience) - .signWith(privateKey, SignatureAlgorithm.RS256).compact(); + Jwts.builder() + .setIssuer(connectorUUID) + .setSubject(connectorUUID) + .setExpiration(Date.from(Instant.now().plusSeconds(86400))) + .setIssuedAt(Date.from(Instant.now())) + .setNotBefore(Date.from(Instant.now())) + .setAudience(targetAudience) + .signWith(privateKey, SignatureAlgorithm.RS256).compact(); //build http client and request for DAPS RequestBody formBody = - new FormBody.Builder() - .add("grant_type", "client_credentials") - .add( - "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - .add("client_assertion", jwt) - .add("scope", "ids_connector") - .build(); + new FormBody.Builder() + .add("grant_type", "client_credentials") + .add( + "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + .add("client_assertion", jwt) + .add("scope", "ids_connector") + .build(); OkHttpClient client = - new OkHttpClient.Builder() - .sslSocketFactory(sslSocketFactory, trustManager) - .connectTimeout(15, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .readTimeout(15, TimeUnit.SECONDS) - .build(); + new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, trustManager) + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .build(); Request request = - new Request.Builder() - .url(dapsUrl.concat("/token")) - .post(formBody) - .build(); + new Request.Builder() + .url(dapsUrl.concat("/token")) + .post(formBody) + .build(); try { //get http response from DAPS @@ -200,24 +200,24 @@ public long verifyToken(byte[] dat, Object securityRequirements) { // create new jwks key resolver, selects jwk based on key ID in jwt header HttpsJwksVerificationKeyResolver jwksKeyResolver - = new HttpsJwksVerificationKeyResolver(httpsJwks); + = new HttpsJwksVerificationKeyResolver(httpsJwks); //create validation requirements JwtConsumer jwtConsumer = - new JwtConsumerBuilder() - .setRequireExpirationTime() // has expiration time - .setAllowedClockSkewInSeconds(30) // leeway in validation time - .setRequireSubject() // has subject - .setExpectedAudience(targetAudience) - .setExpectedIssuer(dapsUrl) // e.g. https://daps.aisec.fraunhofer.de - .setVerificationKeyResolver(jwksKeyResolver) //get decryption key from jwks - .setJweAlgorithmConstraints( - new AlgorithmConstraints( - ConstraintType.WHITELIST, - AlgorithmIdentifiers.RSA_USING_SHA256 - ) - ) - .build(); + new JwtConsumerBuilder() + .setRequireExpirationTime() // has expiration time + .setAllowedClockSkewInSeconds(30) // leeway in validation time + .setRequireSubject() // has subject + .setExpectedAudience(targetAudience) + .setExpectedIssuer(dapsUrl) // e.g. https://daps.aisec.fraunhofer.de + .setVerificationKeyResolver(jwksKeyResolver) //get decryption key from jwks + .setJweAlgorithmConstraints( + new AlgorithmConstraints( + ConstraintType.WHITELIST, + AlgorithmIdentifiers.RSA_USING_SHA256 + ) + ) + .build(); //verify dat JwtClaims claims; @@ -252,15 +252,14 @@ public long verifyToken(byte[] dat, Object securityRequirements) { if (securityRequirements instanceof SecurityRequirements) { SecurityRequirements secRequirements = (SecurityRequirements) securityRequirements; SecurityRequirements providedSecurityProfile = - parseSecurityRequirements(claims.toJson()); + parseSecurityRequirements(claims.toJson()); if (providedSecurityProfile == null) { return -1; } //toDo add further security attribute validation - if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) - { + if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) { LOG.info("DAT is valid and secure"); return validityTime; } else { @@ -312,7 +311,7 @@ private SecurityRequirements parseSecurityRequirements(String dynamicAttrToken) //toDo parse further security attributes return new SecurityRequirements.Builder() - .setAuditLogging(securityProfile.getInt("audit_logging")) - .build(); + .setAuditLogging(securityProfile.getInt("audit_logging")) + .build(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java index 9164d72ad..64f171996 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriverConfig.java @@ -9,97 +9,105 @@ */ public class DefaultDapsDriverConfig { - @NonNull private String dapsUrl = "https://daps.aisec.fraunhofer.de"; - @NonNull private String keyStorePath = ""; - @NonNull private String keyStorePassword = "password"; - @NonNull private String keyAlias = "1"; - @NonNull private String trustStorePath = ""; - @NonNull private String trustStorePassword = "password"; - @NonNull private String connectorUUID = ""; - - public static class Builder { - @NonNull private final DefaultDapsDriverConfig config = new DefaultDapsDriverConfig(); - @NonNull - public Builder setDapsUrl(String dapsUrl) { - this.config.dapsUrl = dapsUrl; - return this; + private String dapsUrl = "https://daps.aisec.fraunhofer.de"; + @NonNull + private String keyStorePath = ""; + @NonNull + private String keyStorePassword = "password"; + @NonNull + private String keyAlias = "1"; + @NonNull + private String trustStorePath = ""; + @NonNull + private String trustStorePassword = "password"; + @NonNull + private String connectorUUID = ""; + + public static class Builder { + @NonNull + private final DefaultDapsDriverConfig config = new DefaultDapsDriverConfig(); + + @NonNull + public Builder setDapsUrl(String dapsUrl) { + this.config.dapsUrl = dapsUrl; + return this; + } + + @NonNull + public Builder setKeyStorePath(String path) { + this.config.keyStorePath = path; + return this; + } + + @NonNull + public Builder setKeyStorePassword(String password) { + this.config.keyStorePassword = password; + return this; + } + + @NonNull + public Builder setKeyAlias(String alias) { + this.config.keyAlias = alias; + return this; + } + + @NonNull + public Builder setTrustStorePath(String path) { + this.config.trustStorePath = path; + return this; + } + + @NonNull + public Builder setTrustStorePassword(String password) { + this.config.trustStorePassword = password; + return this; + } + + @NonNull + public Builder setConnectorUUID(String uuid) { + this.config.connectorUUID = uuid; + return this; + } + + @NonNull + public DefaultDapsDriverConfig build() { + return config; + } } @NonNull - public Builder setKeyStorePath(String path) { - this.config.keyStorePath = path; - return this; + public String getDapsUrl() { + return dapsUrl; } @NonNull - public Builder setKeyStorePassword(String password) { - this.config.keyStorePassword = password; - return this; + public String getKeyStorePath() { + return keyStorePath; } @NonNull - public Builder setKeyAlias(String alias) { - this.config.keyAlias = alias; - return this; + public String getKeyStorePassword() { + return keyStorePassword; } @NonNull - public Builder setTrustStorePath(String path) { - this.config.trustStorePath = path; - return this; + public String getKeyAlias() { + return keyAlias; } @NonNull - public Builder setTrustStorePassword(String password) { - this.config.trustStorePassword = password; - return this; + public String getTrustStorePath() { + return trustStorePath; } @NonNull - public Builder setConnectorUUID(String uuid) { - this.config.connectorUUID = uuid; - return this; + public String getTrustStorePassword() { + return trustStorePassword; } @NonNull - public DefaultDapsDriverConfig build() { - return config; + public String getConnectorUUID() { + return connectorUUID; } - } - - @NonNull - public String getDapsUrl() { - return dapsUrl; - } - - @NonNull - public String getKeyStorePath() { - return keyStorePath; - } - - @NonNull - public String getKeyStorePassword() { - return keyStorePassword; - } - - @NonNull - public String getKeyAlias() { - return keyAlias; - } - - @NonNull - public String getTrustStorePath() { - return trustStorePath; - } - - @NonNull - public String getTrustStorePassword() { - return trustStorePassword; - } - - @NonNull - public String getConnectorUUID() { - return connectorUUID; - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java index 275f82c19..7e588989b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -11,24 +11,25 @@ */ public class SecurityRequirements { - private int auditLogging; - - public static class Builder { - @NonNull private final SecurityRequirements requirements = new SecurityRequirements(); - - @NonNull - public Builder setAuditLogging(int auditLogging) { - this.requirements.auditLogging = auditLogging; - return this; - } - - @NonNull - public SecurityRequirements build() { - return requirements; - } - } - - public int getAuditLogging() { - return auditLogging; - } + private int auditLogging; + + public static class Builder { + @NonNull + private final SecurityRequirements requirements = new SecurityRequirements(); + + @NonNull + public Builder setAuditLogging(int auditLogging) { + this.requirements.auditLogging = auditLogging; + return this; + } + + @NonNull + public SecurityRequirements build() { + return requirements; + } + } + + public int getAuditLogging() { + return auditLogging; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index 67ac13189..8d109d4d1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -18,7 +18,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ +public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager { private static final Logger LOG = LoggerFactory.getLogger(CustomX509ExtendedKeyManager.class); private final String certAlias; @@ -32,7 +32,7 @@ public class CustomX509ExtendedKeyManager extends X509ExtendedKeyManager{ // also cache the aliases and its properties in the following HashMap. private final HashMap cachedAliases = new HashMap<>(); - CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate){ + CustomX509ExtendedKeyManager(String alias, String keyType, final X509ExtendedKeyManager delegate) { super(); this.certAlias = alias; this.keyType = keyType; @@ -51,7 +51,7 @@ public String[] getClientAliases(String keyType, Principal[] issuers) { /* returns an existing certAlias that matches one of the given KeyTypes, or null; called only by client in TLS handshake */ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) { - if (Arrays.asList(keyTypes).contains(this.keyType)){ + if (Arrays.asList(keyTypes).contains(this.keyType)) { if ((cachedAliases.containsKey(this.certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) || Arrays.asList(getClientAliases(keyType, issuers)).contains(this.certAlias)) { @@ -81,7 +81,7 @@ public String[] getServerAliases(String keyType, Principal[] issuers) { /* returns an existing certAlias that matches the given KeyType, or null; called only by server in TLS handshake*/ public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - if (keyType.equals(this.keyType)){ + if (keyType.equals(this.keyType)) { if ((cachedAliases.containsKey(certAlias) && cachedAliases.get(this.certAlias).match(keyType, issuers)) || Arrays.asList(getServerAliases(keyType, issuers)).contains(this.certAlias)) { LOG.debug("CertificateAlias is {}", this.certAlias); @@ -101,7 +101,7 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock /* returns the certificate chain of a given certificateAlias; called by client and server in TLS Handshake after alias was chosen */ public X509Certificate[] getCertificateChain(String certAlias) { - if (certAlias.equals(this.certAlias)){ + if (certAlias.equals(this.certAlias)) { X509Certificate[] ret = delegate.getCertificateChain(certAlias); LOG.debug("Certificate Chain: {}", Arrays.toString(ret)); return ret; @@ -114,9 +114,9 @@ public X509Certificate[] getCertificateChain(String certAlias) { @Override /* returns a privateKey of a given certificateAlias; - * called by client and server in TLS Handshake after alias was chosen */ + * called by client and server in TLS Handshake after alias was chosen */ public PrivateKey getPrivateKey(String certAlias) { - if (certAlias.equals(this.certAlias)){ + if (certAlias.equals(this.certAlias)) { return delegate.getPrivateKey(certAlias); } else { LOG.warn("Invalid certAlias '{}' in getPrivateKey() in class X509ExtendedKeyManager", certAlias); @@ -126,12 +126,12 @@ public PrivateKey getPrivateKey(String certAlias) { } @Override - public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine sslEngine){ + public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine sslEngine) { return delegate.chooseEngineClientAlias(keyType, issuers, sslEngine); } @Override - public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine sslEngine){ + public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine sslEngine) { return delegate.chooseEngineServerAlias(keyType, issuers, sslEngine); } @@ -140,7 +140,7 @@ private static class CachedAliasValue { private final String keyType; //key algorithm type name private final Principal issuer; //certificate issuer - CachedAliasValue(String keyType, Principal issuer){ + CachedAliasValue(String keyType, Principal issuer) { this.keyType = keyType; this.issuer = issuer; } @@ -156,9 +156,9 @@ private static class CachedAliasValue { * * returns true, if the keyAlias fulfills the requirements */ - boolean match(String keyType, Principal[] issuers){ + boolean match(String keyType, Principal[] issuers) { return this.keyType.equals(keyType) && (issuers == null - || Arrays.asList(issuers).contains(issuer)); + || Arrays.asList(issuers).contains(issuer)); } } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index 93550c54b..e12a2c38d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -103,12 +103,12 @@ public static KeyManager[] getX509ExtKeyManager( * throws RuntimeException if key is not available or key access was not permitted */ public static Key getKey( - String keyStorePath, - String keyStorePassword, - String keyAlias + String keyStorePath, + String keyStorePassword, + String keyAlias ) { try ( - InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)) + InputStream jksKeyStoreIn = Files.newInputStream(Paths.get(keyStorePath)) ) { /* create KeyManager for remote authentication */ KeyStore keystore = KeyStore.getInstance("JKS"); @@ -125,7 +125,7 @@ public static Key getKey( } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException - | UnrecoverableKeyException e) { + | UnrecoverableKeyException e) { throw new RuntimeException(e); } } @@ -150,7 +150,8 @@ private static PKIXBuilderParameters filterTrustAnchors(KeyStore keyStore, Date } catch (CertificateException e) { return false; } - return true; }).collect(Collectors.toSet()); + return true; + }).collect(Collectors.toSet()); // Create PKIXBuilderParameters parameters return new PKIXBuilderParameters(validTrustAnchors, new X509CertSelector()); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java index 87fbc1ca6..2454756fb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatProverDummy.java @@ -18,7 +18,7 @@ public class RatProverDummy extends RatProverDriver { private final BlockingQueue queue = new LinkedBlockingQueue<>(); - public RatProverDummy(){ + public RatProverDummy() { super(); } @@ -33,11 +33,11 @@ public void delegate(byte[] message) { @Override public void run() { int countDown = 2; - while (running){ + while (running) { try { sleep(1000); fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, - "test".getBytes()); + "test".getBytes()); if (LOG.isDebugEnabled()) { LOG.debug("Prover waits"); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java index 9127ddfae..f05c165e6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/dummy/RatVerifierDummy.java @@ -18,7 +18,7 @@ public class RatVerifierDummy extends RatVerifierDriver { private final BlockingQueue queue = new LinkedBlockingQueue<>(); - public RatVerifierDummy(){ + public RatVerifierDummy() { super(); } @@ -31,9 +31,9 @@ public void delegate(byte[] message) { } @Override - public void run(){ + public void run() { int countDown = 2; - while (running){ + while (running) { try { sleep(1000); if (LOG.isDebugEnabled()) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java index 0639288dc..268dc1093 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dHelper.java @@ -9,75 +9,76 @@ import java.security.cert.Certificate; public class TPM2dHelper { - private static final Logger LOG = LoggerFactory.getLogger(TPM2dHelper.class); - private static final SecureRandom sr = new SecureRandom(); + private static final Logger LOG = LoggerFactory.getLogger(TPM2dHelper.class); + private static final SecureRandom sr = new SecureRandom(); - private TPM2dHelper() {} + private TPM2dHelper() { + } - /** - * Generate a crypto-secure random hex String of length numChars - * - * @param numBytes Desired String length - * @return The generated crypto-secure random hex String - */ - static byte[] generateNonce(int numBytes) { - byte[] randBytes = new byte[numBytes]; - sr.nextBytes(randBytes); - return randBytes; - } + /** + * Generate a crypto-secure random hex String of length numChars + * + * @param numBytes Desired String length + * @return The generated crypto-secure random hex String + */ + static byte[] generateNonce(int numBytes) { + byte[] randBytes = new byte[numBytes]; + sr.nextBytes(randBytes); + return randBytes; + } - /** - * Calculate SHA-1 hash of (nonce|certificate). - * - * @param nonce The plain, initial nonce - * @param certificate The certificate to hash-combine with the nonce - * @return The new nonce, updated with the given certificate using SHA-1 - */ - static byte[] calculateHash(byte[] nonce, @Nullable Certificate certificate) { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - digest.update(nonce); - if (certificate != null) { - digest.update(certificate.getEncoded()); - } else { - if (LOG.isWarnEnabled()) { - LOG.warn( - "No client certificate available. Cannot bind nonce to public key to prevent masquerading attack. TLS misconfiguration!"); + /** + * Calculate SHA-1 hash of (nonce|certificate). + * + * @param nonce The plain, initial nonce + * @param certificate The certificate to hash-combine with the nonce + * @return The new nonce, updated with the given certificate using SHA-1 + */ + static byte[] calculateHash(byte[] nonce, @Nullable Certificate certificate) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(nonce); + if (certificate != null) { + digest.update(certificate.getEncoded()); + } else { + if (LOG.isWarnEnabled()) { + LOG.warn( + "No client certificate available. Cannot bind nonce to public key to prevent masquerading attack. TLS misconfiguration!"); + } + } + return digest.digest(); + } catch (Exception e1) { + LOG.error("Could not create hash of own nonce and local certificate", e1); + return nonce; } - } - return digest.digest(); - } catch (Exception e1) { - LOG.error("Could not create hash of own nonce and local certificate", e1); - return nonce; } - } - static class ByteArrayUtil { + static class ByteArrayUtil { - private static final String[] lookup = new String[256]; + private static final String[] lookup = new String[256]; - static { - for (int i = 0; i < lookup.length; ++i) { - if (i < 16) { - lookup[i] = "0" + Integer.toHexString(i); - } else { - lookup[i] = Integer.toHexString(i); + static { + for (int i = 0; i < lookup.length; ++i) { + if (i < 16) { + lookup[i] = "0" + Integer.toHexString(i); + } else { + lookup[i] = Integer.toHexString(i); + } + } } - } - } - static String toPrintableHexString(byte[] bytes) { - StringBuilder s = new StringBuilder(); - for (int i = 0; i < bytes.length; ++i) { - if (i > 0 && i % 16 == 0) { - s.append('\n'); - } else { - s.append(' '); + static String toPrintableHexString(byte[] bytes) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < bytes.length; ++i) { + if (i > 0 && i % 16 == 0) { + s.append('\n'); + } else { + s.append(' '); + } + s.append(lookup[bytes[i] & 0xff]); + } + return s.toString(); } - s.append(lookup[bytes[i] & 0xff]); - } - return s.toString(); } - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java index effae50fe..e01bf145f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dMessageFactory.java @@ -2,8 +2,8 @@ import com.google.protobuf.ByteString; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d.Code; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.*; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.RemoteToTpm2d.Code; import java.util.List; @@ -14,66 +14,66 @@ */ public class TPM2dMessageFactory { - static Tpm2dMessageWrapper getAttestationChallengeMessage( - byte[] nonce, - IdsAttestationType aType, - int pcrIndices - ) { - return Tpm2dMessageWrapper.newBuilder().setRatChallenge( - Tpm2dRatChallenge.newBuilder() - .setAtype(aType) - .setNonce(ByteString.copyFrom(nonce)) - .setPcrIndices(pcrIndices) - .build() - ).build(); - } + static Tpm2dMessageWrapper getAttestationChallengeMessage( + byte[] nonce, + IdsAttestationType aType, + int pcrIndices + ) { + return Tpm2dMessageWrapper.newBuilder().setRatChallenge( + Tpm2dRatChallenge.newBuilder() + .setAtype(aType) + .setNonce(ByteString.copyFrom(nonce)) + .setPcrIndices(pcrIndices) + .build() + ).build(); + } - static Tpm2dMessageWrapper getAttestationResponseMessage( - IdsAttestationType aType, - String hash_alg, - ByteString quoted, - ByteString signature, - List pcrValues, - ByteString certificate - ) { - return Tpm2dMessageWrapper.newBuilder().setRatResponse( - Tpm2dRatResponse.newBuilder() - .setAtype(aType) - .setHashAlg(hash_alg) - .setQuoted(quoted) - .setSignature(signature) - .addAllPcrValues(pcrValues) - .setCertificate(certificate) - .build() - ).build(); - } + static Tpm2dMessageWrapper getAttestationResponseMessage( + IdsAttestationType aType, + String hash_alg, + ByteString quoted, + ByteString signature, + List pcrValues, + ByteString certificate + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResponse( + Tpm2dRatResponse.newBuilder() + .setAtype(aType) + .setHashAlg(hash_alg) + .setQuoted(quoted) + .setSignature(signature) + .addAllPcrValues(pcrValues) + .setCertificate(certificate) + .build() + ).build(); + } - static Tpm2dMessageWrapper getAttestationResponseMessage( - Tpm2dToRemote response - ) { - return Tpm2dMessageWrapper.newBuilder().setRatResponse( - Tpm2dRatResponse.newBuilder() - .setAtype(response.getAtype()) - .setHashAlg(response.getHalg().name()) - .setQuoted(response.getQuoted()) - .setSignature(response.getSignature()) - .addAllPcrValues(response.getPcrValuesList()) - .setCertificate(response.getCertificate()) - .build() - ).build(); - } + static Tpm2dMessageWrapper getAttestationResponseMessage( + Tpm2dToRemote response + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResponse( + Tpm2dRatResponse.newBuilder() + .setAtype(response.getAtype()) + .setHashAlg(response.getHalg().name()) + .setQuoted(response.getQuoted()) + .setSignature(response.getSignature()) + .addAllPcrValues(response.getPcrValuesList()) + .setCertificate(response.getCertificate()) + .build() + ).build(); + } - static Tpm2dMessageWrapper getAttestationResultMessage( - //IdsAttestationType aType, - boolean result - ) { - return Tpm2dMessageWrapper.newBuilder().setRatResult( - Tpm2dRatResult.newBuilder() - //.setAtype(aType) - .setResult(result) - .build() - ).build(); - } + static Tpm2dMessageWrapper getAttestationResultMessage( + //IdsAttestationType aType, + boolean result + ) { + return Tpm2dMessageWrapper.newBuilder().setRatResult( + Tpm2dRatResult.newBuilder() + //.setAtype(aType) + .setResult(result) + .build() + ).build(); + } /*static Tpm2dMessageWrapper getAttestationRepositoryRequestMessage( IdsAttestationType aType, @@ -94,16 +94,16 @@ static Tpm2dMessageWrapper getAttestationRepositoryResponseMessage() { ).build(); }*/ - static RemoteToTpm2d getRemoteToTPM2dMessage( - IdsAttestationType aType, - byte[] hash, - int pcrIndices - ) { - return RemoteToTpm2d.newBuilder() - .setAtype(aType) - .setQualifyingData(ByteString.copyFrom(hash)) - .setCode(Code.ATTESTATION_REQ) - .setPcrs(pcrIndices) - .build(); - } + static RemoteToTpm2d getRemoteToTPM2dMessage( + IdsAttestationType aType, + byte[] hash, + int pcrIndices + ) { + return RemoteToTpm2d.newBuilder() + .setAtype(aType) + .setQualifyingData(ByteString.copyFrom(hash)) + .setCode(Code.ATTESTATION_REQ) + .setPcrs(pcrIndices) + .build(); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java index b2ff18fb0..2603c425a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProver.java @@ -3,7 +3,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.*; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,197 +17,197 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class TPM2dProver extends RatProverDriver { - private static final Logger LOG = LoggerFactory.getLogger(TPM2dProver.class); - - /* - * ******************* Protocol ******************* - * - * Verifier: (Challenger) - * ------------------------- - * Generate NonceV - * create RatChallenge (NonceV, aType, pcr_mask) - * ------------------------- - * - * Prover: (Responder) - * ------------------------- - * get RatChallenge (NonceV, aType, pcr_mask) - * hash = calculateHash(nonceV, certV) - * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) - * response = TPM2dToRemote = tpmSocket.attestationRequest(req) - * create AttestationResponse from tpm response - * ------------------------- - * - * Verifier: (Responder) - * ------------------------- - * get AttestationResponse - * hash = calculateHash(nonceV, certV) - * check signature(response, hash) - * check repo(aType, response, ttpUri) - * create RatResult - * ------------------------- - * - * Prover: (Requester) - * ------------------------- - * get AttestationResult - * ------------------------- - * - */ - - private final BlockingQueue queue = new LinkedBlockingQueue<>(); - private TPM2dProverConfig config = new TPM2dProverConfig.Builder().build(); - - public TPM2dProver(){ - super(); - } - - @Override - public void setConfig(Object config) { - if (config instanceof TPM2dProverConfig) { - if (LOG.isDebugEnabled()) { - LOG.debug("Set rat prover config"); - } - this.config = (TPM2dProverConfig) config; - } else { - if (LOG.isWarnEnabled()) { - LOG.warn("Invalid prover config"); - } + private static final Logger LOG = LoggerFactory.getLogger(TPM2dProver.class); + + /* + * ******************* Protocol ******************* + * + * Verifier: (Challenger) + * ------------------------- + * Generate NonceV + * create RatChallenge (NonceV, aType, pcr_mask) + * ------------------------- + * + * Prover: (Responder) + * ------------------------- + * get RatChallenge (NonceV, aType, pcr_mask) + * hash = calculateHash(nonceV, certV) + * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) + * response = TPM2dToRemote = tpmSocket.attestationRequest(req) + * create AttestationResponse from tpm response + * ------------------------- + * + * Verifier: (Responder) + * ------------------------- + * get AttestationResponse + * hash = calculateHash(nonceV, certV) + * check signature(response, hash) + * check repo(aType, response, ttpUri) + * create RatResult + * ------------------------- + * + * Prover: (Requester) + * ------------------------- + * get AttestationResult + * ------------------------- + * + */ + + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + private TPM2dProverConfig config = new TPM2dProverConfig.Builder().build(); + + public TPM2dProver() { + super(); } - } - @Override - public void delegate(byte[] message) { - queue.add(message); - if (LOG.isDebugEnabled()) { - LOG.debug("Delegated to prover"); - } - } - - @Override - public void run() { - //TPM2d Challenge-Response Protocol - - // wait for RatChallenge from Verifier - byte[] msg; - try { - msg = queue.take(); - if (LOG.isDebugEnabled()) { - LOG.debug("Prover receives new message"); - } - } catch (InterruptedException e) { - if (this.running){ - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - } - return; - } - - // parse body to expected tpm2d message wrapper - Tpm2dMessageWrapper tpm2dMessageWrapper; - try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); - } catch (InvalidProtocolBufferException e) { - LOG.error("Cannot parse IdscpRatVerifier body", e); - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - // check if wrapper contains expected rat challenge - if (!tpm2dMessageWrapper.hasRatChallenge()) { - //unexpected message - if (LOG.isWarnEnabled()) { - LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatChallenge"); - } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Get rat challenge from rat verifier"); - } - Tpm2dRatChallenge challenge = tpm2dMessageWrapper.getRatChallenge(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Requesting attestation from TPM ..."); + @Override + public void setConfig(Object config) { + if (config instanceof TPM2dProverConfig) { + if (LOG.isDebugEnabled()) { + LOG.debug("Set rat prover config"); + } + this.config = (TPM2dProverConfig) config; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("Invalid prover config"); + } + } } - // hash - byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), - config.getRemoteCertificate()); - - // generate RemoteToTPM2dRequest - RemoteToTpm2d tpmRequest = TPM2dMessageFactory.getRemoteToTPM2dMessage( - challenge.getAtype(), - hash, - challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 - ); - - // get TPM response - Tpm2dToRemote tpmResponse; - try { - TPM2dSocket tpmSocket = new TPM2dSocket(config.getTpm2dHost()); - tpmResponse = tpmSocket.requestAttestation(tpmRequest); - } catch (IOException e) { - LOG.error("Cannot access TPM", e); - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; + @Override + public void delegate(byte[] message) { + queue.add(message); + if (LOG.isDebugEnabled()) { + LOG.debug("Delegated to prover"); + } } - // create Tpm2dResponse - byte[] response = TPM2dMessageFactory.getAttestationResponseMessage(tpmResponse) - .toByteArray(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Send rat response to verifier"); - } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, response); - - // wait for result - try { - msg = queue.take(); - if (LOG.isDebugEnabled()) { - LOG.debug("Prover receives new message"); - } - } catch (InterruptedException e) { - if (this.running) { - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - } - return; - } - - // parse body to expected tpm2d message wrapper - try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); - } catch (InvalidProtocolBufferException e) { - LOG.error("Cannot parse IdscpRatVerifier body", e); - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - // check if wrapper contains expected rat result - if (!tpm2dMessageWrapper.hasRatResult()) { - //unexpected message - if (LOG.isWarnEnabled()) { - LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResult"); - } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); - return; - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Get rat challenge from rat verifier"); - } - Tpm2dRatResult result = tpm2dMessageWrapper.getRatResult(); - - // notify fsm - if (result.getResult()) { - if (LOG.isDebugEnabled()) { - LOG.debug("Attestation succeed"); - } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); - } else { - if (LOG.isWarnEnabled()) { - LOG.warn("Attestation failed"); - } - fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + @Override + public void run() { + //TPM2d Challenge-Response Protocol + + // wait for RatChallenge from Verifier + byte[] msg; + try { + msg = queue.take(); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover receives new message"); + } + } catch (InterruptedException e) { + if (this.running) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + } + return; + } + + // parse body to expected tpm2d message wrapper + Tpm2dMessageWrapper tpm2dMessageWrapper; + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatVerifier body", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if wrapper contains expected rat challenge + if (!tpm2dMessageWrapper.hasRatChallenge()) { + //unexpected message + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatChallenge"); + } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Get rat challenge from rat verifier"); + } + Tpm2dRatChallenge challenge = tpm2dMessageWrapper.getRatChallenge(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Requesting attestation from TPM ..."); + } + + // hash + byte[] hash = TPM2dHelper.calculateHash(challenge.getNonce().toByteArray(), + config.getRemoteCertificate()); + + // generate RemoteToTPM2dRequest + RemoteToTpm2d tpmRequest = TPM2dMessageFactory.getRemoteToTPM2dMessage( + challenge.getAtype(), + hash, + challenge.hasPcrIndices() ? challenge.getPcrIndices() : 0 + ); + + // get TPM response + Tpm2dToRemote tpmResponse; + try { + TPM2dSocket tpmSocket = new TPM2dSocket(config.getTpm2dHost()); + tpmResponse = tpmSocket.requestAttestation(tpmRequest); + } catch (IOException e) { + LOG.error("Cannot access TPM", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // create Tpm2dResponse + byte[] response = TPM2dMessageFactory.getAttestationResponseMessage(tpmResponse) + .toByteArray(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Send rat response to verifier"); + } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_MSG, response); + + // wait for result + try { + msg = queue.take(); + if (LOG.isDebugEnabled()) { + LOG.debug("Prover receives new message"); + } + } catch (InterruptedException e) { + if (this.running) { + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + } + return; + } + + // parse body to expected tpm2d message wrapper + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatVerifier body", e); + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + // check if wrapper contains expected rat result + if (!tpm2dMessageWrapper.hasRatResult()) { + //unexpected message + if (LOG.isWarnEnabled()) { + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResult"); + } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + return; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Get rat challenge from rat verifier"); + } + Tpm2dRatResult result = tpm2dMessageWrapper.getRatResult(); + + // notify fsm + if (result.getResult()) { + if (LOG.isDebugEnabled()) { + LOG.debug("Attestation succeed"); + } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_OK, null); + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("Attestation failed"); + } + fsmListener.onRatProverMessage(InternalControlMessage.RAT_PROVER_FAILED, null); + } } - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java index b9a64a8c8..99f31acd7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dProverConfig.java @@ -11,40 +11,41 @@ */ public class TPM2dProverConfig { - private Certificate remoteCertificate; - @NonNull private String tpm2dHost; + private Certificate remoteCertificate; + @NonNull + private String tpm2dHost; - private TPM2dProverConfig() { - tpm2dHost = System.getenv("TPM_HOST") != null ? - System.getenv("TPM_HOST") : "localhost"; - } + private TPM2dProverConfig() { + tpm2dHost = System.getenv("TPM_HOST") != null ? + System.getenv("TPM_HOST") : "localhost"; + } - public static class Builder { - private static final TPM2dProverConfig config = new TPM2dProverConfig(); + public static class Builder { + private static final TPM2dProverConfig config = new TPM2dProverConfig(); - @NonNull - public Builder setRemoteCertificate(Certificate remoteCert) { - config.remoteCertificate = remoteCert; - return this; - } + @NonNull + public Builder setRemoteCertificate(Certificate remoteCert) { + config.remoteCertificate = remoteCert; + return this; + } - @NonNull - public Builder setTpmHost(String host) { - config.tpm2dHost = host; - return this; - } + @NonNull + public Builder setTpmHost(String host) { + config.tpm2dHost = host; + return this; + } - public TPM2dProverConfig build() { - return config; + public TPM2dProverConfig build() { + return config; + } } - } - public Certificate getRemoteCertificate() { - return remoteCertificate; - } + public Certificate getRemoteCertificate() { + return remoteCertificate; + } - @NonNull - public String getTpm2dHost() { - return tpm2dHost; - } + @NonNull + public String getTpm2dHost() { + return tpm2dHost; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java index 943de0690..56c32cd37 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dSocket.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.RemoteToTpm2d; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dToRemote; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.RemoteToTpm2d; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.Tpm2dToRemote; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -13,23 +13,23 @@ */ public class TPM2dSocket extends Socket { - private final DataInputStream is; - private final DataOutputStream os; + private final DataInputStream is; + private final DataOutputStream os; - public TPM2dSocket(String host) throws IOException { - super(host, 9505); - is = new DataInputStream(this.getInputStream()); - os = new DataOutputStream(this.getOutputStream()); - } + public TPM2dSocket(String host) throws IOException { + super(host, 9505); + is = new DataInputStream(this.getInputStream()); + os = new DataOutputStream(this.getOutputStream()); + } - public Tpm2dToRemote requestAttestation(RemoteToTpm2d request) throws IOException { - // Write attestation request message - byte[] requestBytes = request.toByteArray(); - os.writeInt(requestBytes.length); - os.write(requestBytes); - // Read attestation result message - byte[] resultBytes = new byte[is.readInt()]; - is.readFully(resultBytes); - return Tpm2dToRemote.parseFrom(resultBytes); - } + public Tpm2dToRemote requestAttestation(RemoteToTpm2d request) throws IOException { + // Write attestation request message + byte[] requestBytes = request.toByteArray(); + os.writeInt(requestBytes.length); + os.write(requestBytes); + // Read attestation result message + byte[] resultBytes = new byte[is.readInt()]; + is.readFully(resultBytes); + return Tpm2dToRemote.parseFrom(resultBytes); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java index 3b65cc1a8..03f470053 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifier.java @@ -3,8 +3,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.InternalControlMessage; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dMessageWrapper; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.Tpm2dRatResponse; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.Tpm2dMessageWrapper; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.Tpm2dRatResponse; import org.checkerframework.checker.nullness.qual.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,254 +28,254 @@ * A TPM2d RatVerifier driver that verifies the remote peer's identity using TPM2d */ public class TPM2dVerifier extends RatVerifierDriver { - private static final Logger LOG = LoggerFactory.getLogger(TPM2dVerifier.class); - - /* - * ******************* Protocol ******************* - * - * Verifier: (Challenger) - * ------------------------- - * Generate NonceV - * create RatChallenge (NonceV, aType, pcr_mask) - * ------------------------- - * - * Prover: (Responder) - * ------------------------- - * get RatChallenge (NonceV, aType, pcr_mask) - * hash = calculateHash(nonceV, certV) - * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) - * response = TPM2dToRemote = tpmSocket.attestationRequest(req) - * create AttestationResponse from tpm response - * ------------------------- - * - * Verifier: (Responder) - * ------------------------- - * get AttestationResponse - * hash = calculateHash(nonceV, certV) - * check signature(response, hash) - * check repo(aType, response, ttpUri) - * create RatResult - * ------------------------- - * - * Prover: (Requester) - * ------------------------- - * get AttestationResult - * ------------------------- - * - */ - - private final BlockingQueue queue = new LinkedBlockingQueue<>(); - private TPM2dVerifierConfig config = new TPM2dVerifierConfig.Builder().build(); - - public TPM2dVerifier(){ - super(); - } - - @Override - public void setConfig(Object config) { - if (config instanceof TPM2dVerifierConfig) { - LOG.debug("Set rat verifier config"); - this.config = (TPM2dVerifierConfig) config; - } else { - LOG.warn("Invalid config"); - } - } - - @Override - public void delegate(byte[] message) { - queue.add(message); - LOG.debug("Delegated to Verifier"); - } - - @Override - public void run(){ - //TPM2d Challenge-Response Protocol - - // create rat challenge with fresh nonce - LOG.debug("Generate and send rat challenge for rat prover"); - byte[] nonce = TPM2dHelper.generateNonce(20); - - // send challenge as RAT Verifier Message - byte[] ratChallenge = TPM2dMessageFactory.getAttestationChallengeMessage( - nonce, config.getExpectedAType(), config.getExpectedAttestationMask()).toByteArray(); - - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratChallenge); - - // wait for attestation response - byte[] msg; - try { - msg = queue.take(); - LOG.debug("Verifier receives new message"); - } catch (InterruptedException e) { - if (this.running) { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - } - return; + private static final Logger LOG = LoggerFactory.getLogger(TPM2dVerifier.class); + + /* + * ******************* Protocol ******************* + * + * Verifier: (Challenger) + * ------------------------- + * Generate NonceV + * create RatChallenge (NonceV, aType, pcr_mask) + * ------------------------- + * + * Prover: (Responder) + * ------------------------- + * get RatChallenge (NonceV, aType, pcr_mask) + * hash = calculateHash(nonceV, certV) + * req = generate RemoteToTPM2dRequest(hash, aType, pcr_mask) + * response = TPM2dToRemote = tpmSocket.attestationRequest(req) + * create AttestationResponse from tpm response + * ------------------------- + * + * Verifier: (Responder) + * ------------------------- + * get AttestationResponse + * hash = calculateHash(nonceV, certV) + * check signature(response, hash) + * check repo(aType, response, ttpUri) + * create RatResult + * ------------------------- + * + * Prover: (Requester) + * ------------------------- + * get AttestationResult + * ------------------------- + * + */ + + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + private TPM2dVerifierConfig config = new TPM2dVerifierConfig.Builder().build(); + + public TPM2dVerifier() { + super(); } - // parse body to expected tpm2d message wrapper - Tpm2dMessageWrapper tpm2dMessageWrapper; - try { - tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); - } catch (InvalidProtocolBufferException e) { - LOG.error("Cannot parse IdscpRatProver body", e); - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - return; + @Override + public void setConfig(Object config) { + if (config instanceof TPM2dVerifierConfig) { + LOG.debug("Set rat verifier config"); + this.config = (TPM2dVerifierConfig) config; + } else { + LOG.warn("Invalid config"); + } } - // check if wrapper contains expected rat response - if (!tpm2dMessageWrapper.hasRatResponse()) { - //unexpected message - LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResponse"); - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - return; + @Override + public void delegate(byte[] message) { + queue.add(message); + LOG.debug("Delegated to Verifier"); } - LOG.debug("Get rat response from remote prover"); - //validate rat response - Tpm2dRatResponse resp = tpm2dMessageWrapper.getRatResponse(); + @Override + public void run() { + //TPM2d Challenge-Response Protocol + + // create rat challenge with fresh nonce + LOG.debug("Generate and send rat challenge for rat prover"); + byte[] nonce = TPM2dHelper.generateNonce(20); + + // send challenge as RAT Verifier Message + byte[] ratChallenge = TPM2dMessageFactory.getAttestationChallengeMessage( + nonce, config.getExpectedAType(), config.getExpectedAttestationMask()).toByteArray(); + + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratChallenge); + + // wait for attestation response + byte[] msg; + try { + msg = queue.take(); + LOG.debug("Verifier receives new message"); + } catch (InterruptedException e) { + if (this.running) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + } + return; + } - LOG.debug("Validate rat response: signature and rat repository checks"); + // parse body to expected tpm2d message wrapper + Tpm2dMessageWrapper tpm2dMessageWrapper; + try { + tpm2dMessageWrapper = Tpm2dMessageWrapper.parseFrom(msg); + } catch (InvalidProtocolBufferException e) { + LOG.error("Cannot parse IdscpRatProver body", e); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } - // validate signature - boolean result = true; - byte[] hash = TPM2dHelper.calculateHash(nonce, config.getLocalCertificate()); + // check if wrapper contains expected rat response + if (!tpm2dMessageWrapper.hasRatResponse()) { + //unexpected message + LOG.warn("Unexpected message from RatProver: Expected Tpm2dRatResponse"); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + return; + } - if (!checkSignature(resp, hash)) { - result = false; - LOG.warn("Invalid rat signature"); - } + LOG.debug("Get rat response from remote prover"); + //validate rat response + Tpm2dRatResponse resp = tpm2dMessageWrapper.getRatResponse(); - // toDo check rat repo!!!!!!!!! --> Problems with current Rat Repo Protobuf format + LOG.debug("Validate rat response: signature and rat repository checks"); - // create and send rat result - LOG.debug("Send rat result to remote prover"); - byte[] ratResult = TPM2dMessageFactory.getAttestationResultMessage(result).toByteArray(); - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratResult); + // validate signature + boolean result = true; + byte[] hash = TPM2dHelper.calculateHash(nonce, config.getLocalCertificate()); - // notify fsm about result - if (result) { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); - } else { - fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); - } - } + if (!checkSignature(resp, hash)) { + result = false; + LOG.warn("Invalid rat signature"); + } - private boolean checkSignature(@NonNull Tpm2dRatResponse response, byte[] hash) { - byte[] byteSignature = response.getSignature().toByteArray(); - byte[] byteCert = response.getCertificate().toByteArray(); - byte[] byteQuoted = response.getQuoted().toByteArray(); + // toDo check rat repo!!!!!!!!! --> Problems with current Rat Repo Protobuf format - if (LOG.isDebugEnabled()) { - LOG.debug("signature: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature)); - LOG.debug("cert: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteCert)); - LOG.debug("quoted: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted)); - } + // create and send rat result + LOG.debug("Send rat result to remote prover"); + byte[] ratResult = TPM2dMessageFactory.getAttestationResultMessage(result).toByteArray(); + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_MSG, ratResult); - if (byteSignature.length == 0 || byteCert.length == 0 || byteQuoted.length == 0) { - LOG.warn("Some required part (signature, cert or quoted) is empty!"); - return false; + // notify fsm about result + if (result) { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_OK, null); + } else { + fsmListener.onRatVerifierMessage(InternalControlMessage.RAT_VERIFIER_FAILED, null); + } } - try { - CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - - // Load trust anchor certificate - final X509Certificate rootCertificate; - Path rootCertPath = FileSystems.getDefault().getPath("etc", "rootca-cert.pem"); - try (BufferedReader reader = - Files.newBufferedReader(rootCertPath, StandardCharsets.US_ASCII)) { - StringBuilder builder = new StringBuilder(); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - if (!line.startsWith("-")) { - builder.append(line.trim()); - } + private boolean checkSignature(@NonNull Tpm2dRatResponse response, byte[] hash) { + byte[] byteSignature = response.getSignature().toByteArray(); + byte[] byteCert = response.getCertificate().toByteArray(); + byte[] byteQuoted = response.getQuoted().toByteArray(); + + if (LOG.isDebugEnabled()) { + LOG.debug("signature: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature)); + LOG.debug("cert: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteCert)); + LOG.debug("quoted: {}", TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted)); } - byte[] rootCertBytes = Base64.getDecoder().decode(builder.toString()); - rootCertificate = - (X509Certificate) - certFactory.generateCertificate(new ByteArrayInputStream(rootCertBytes)); - } catch (Exception e) { - LOG.error("Error parsing root certificate", e); - return false; - } - - // Create X509Certificate instance from certBytes - final X509Certificate certificate = - (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(byteCert)); - // Verify the TPM certificate - try { - certificate.verify(rootCertificate.getPublicKey()); - } catch (Exception e) { - LOG.error("TPM certificate is invalid", e); - return false; - } - - // Construct a new TPMT_SIGNATURE instance from byteSignature bytes - final TPMT_SIGNATURE tpmtSignature; - try { - tpmtSignature = TPMT_SIGNATURE.fromTpm(byteSignature); - } catch (Exception ex) { - LOG.warn( - "Could not create a TPMT_SIGNATURE from bytes:\n" - + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature), - ex); - return false; - } - - // Construct a new TPMS_ATTEST instance from byteQuoted bytes - final TPMS_ATTEST tpmsAttest; - try { - tpmsAttest = TPMS_ATTEST.fromTpm(byteQuoted); - } catch (Exception ex) { - LOG.warn( - "Could not create a TPMS_ATTEST from bytes:\n" - + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted), - ex); - return false; - } - - // check hash value (extra data) against expected hash - byte[] extraBytes = tpmsAttest.extraData; - if (!Arrays.equals(extraBytes, hash)) { - if (LOG.isWarnEnabled()) { - LOG.warn( - "The hash (extra data) in TPMS_ATTEST structure is invalid!" - + "\nextra data: {}\nhash: {}", - TPM2dHelper.ByteArrayUtil.toPrintableHexString(extraBytes), - TPM2dHelper.ByteArrayUtil.toPrintableHexString(hash)); + + if (byteSignature.length == 0 || byteCert.length == 0 || byteQuoted.length == 0) { + LOG.warn("Some required part (signature, cert or quoted) is empty!"); + return false; + } + + try { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + + // Load trust anchor certificate + final X509Certificate rootCertificate; + Path rootCertPath = FileSystems.getDefault().getPath("etc", "rootca-cert.pem"); + try (BufferedReader reader = + Files.newBufferedReader(rootCertPath, StandardCharsets.US_ASCII)) { + StringBuilder builder = new StringBuilder(); + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (!line.startsWith("-")) { + builder.append(line.trim()); + } + } + byte[] rootCertBytes = Base64.getDecoder().decode(builder.toString()); + rootCertificate = + (X509Certificate) + certFactory.generateCertificate(new ByteArrayInputStream(rootCertBytes)); + } catch (Exception e) { + LOG.error("Error parsing root certificate", e); + return false; + } + + // Create X509Certificate instance from certBytes + final X509Certificate certificate = + (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(byteCert)); + // Verify the TPM certificate + try { + certificate.verify(rootCertificate.getPublicKey()); + } catch (Exception e) { + LOG.error("TPM certificate is invalid", e); + return false; + } + + // Construct a new TPMT_SIGNATURE instance from byteSignature bytes + final TPMT_SIGNATURE tpmtSignature; + try { + tpmtSignature = TPMT_SIGNATURE.fromTpm(byteSignature); + } catch (Exception ex) { + LOG.warn( + "Could not create a TPMT_SIGNATURE from bytes:\n" + + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteSignature), + ex); + return false; + } + + // Construct a new TPMS_ATTEST instance from byteQuoted bytes + final TPMS_ATTEST tpmsAttest; + try { + tpmsAttest = TPMS_ATTEST.fromTpm(byteQuoted); + } catch (Exception ex) { + LOG.warn( + "Could not create a TPMS_ATTEST from bytes:\n" + + TPM2dHelper.ByteArrayUtil.toPrintableHexString(byteQuoted), + ex); + return false; + } + + // check hash value (extra data) against expected hash + byte[] extraBytes = tpmsAttest.extraData; + if (!Arrays.equals(extraBytes, hash)) { + if (LOG.isWarnEnabled()) { + LOG.warn( + "The hash (extra data) in TPMS_ATTEST structure is invalid!" + + "\nextra data: {}\nhash: {}", + TPM2dHelper.ByteArrayUtil.toPrintableHexString(extraBytes), + TPM2dHelper.ByteArrayUtil.toPrintableHexString(hash)); + } + return false; + } + + // Check signature of attestation + final int tpmSigAlg = tpmtSignature.GetUnionSelector_signature(); + final int tpmSigHashAlg; + final byte[] tpmSig; + if (tpmSigAlg == TPM_ALG_ID.RSAPSS.toInt()) { + tpmSigHashAlg = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).hash.toInt(); + tpmSig = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).sig; + } else if (tpmSigAlg == TPM_ALG_ID.RSASSA.toInt()) { + tpmSigHashAlg = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).hash.toInt(); + tpmSig = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).sig; + } else { + throw new Exception( + "Unknown or unimplemented signature scheme: " + tpmtSignature.signature.getClass()); + } + if (tpmSigHashAlg != TPM_ALG_ID.SHA256.toInt()) { + throw new Exception("Only SHA256withRSA TPM signature hash algorithm is allowed!"); + } + Signature sig = Signature.getInstance("SHA256withRSA"); + sig.initVerify(certificate.getPublicKey()); + sig.update(byteQuoted); + boolean result = sig.verify(tpmSig); + if (!result && LOG.isWarnEnabled()) { + LOG.warn("Attestation signature invalid!"); + } + return result; + } catch (Exception ex) { + LOG.warn("Error during attestation validation", ex); + return false; } - return false; - } - - // Check signature of attestation - final int tpmSigAlg = tpmtSignature.GetUnionSelector_signature(); - final int tpmSigHashAlg; - final byte[] tpmSig; - if (tpmSigAlg == TPM_ALG_ID.RSAPSS.toInt()) { - tpmSigHashAlg = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).hash.toInt(); - tpmSig = ((TPMS_SIGNATURE_RSAPSS) tpmtSignature.signature).sig; - } else if (tpmSigAlg == TPM_ALG_ID.RSASSA.toInt()) { - tpmSigHashAlg = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).hash.toInt(); - tpmSig = ((TPMS_SIGNATURE_RSASSA) tpmtSignature.signature).sig; - } else { - throw new Exception( - "Unknown or unimplemented signature scheme: " + tpmtSignature.signature.getClass()); - } - if (tpmSigHashAlg != TPM_ALG_ID.SHA256.toInt()) { - throw new Exception("Only SHA256withRSA TPM signature hash algorithm is allowed!"); - } - Signature sig = Signature.getInstance("SHA256withRSA"); - sig.initVerify(certificate.getPublicKey()); - sig.update(byteQuoted); - boolean result = sig.verify(tpmSig); - if (!result && LOG.isWarnEnabled()) { - LOG.warn("Attestation signature invalid!"); - } - return result; - } catch (Exception ex) { - LOG.warn("Error during attestation validation", ex); - return false; } - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java index 3dee225a5..db9d0ad1d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/rat/tpm2d/TPM2dVerifierConfig.java @@ -1,6 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d; -import de.fhg.aisec.ids.messages.Tpm2dAttestation.IdsAttestationType; +import de.fhg.aisec.ids.idscp2.messages.Tpm2dAttestation.IdsAttestationType; import org.checkerframework.checker.nullness.qual.NonNull; import java.net.URI; @@ -14,65 +14,67 @@ */ public class TPM2dVerifierConfig { - private Certificate localCertificate; - @NonNull private URI ttpUri; - @NonNull private IdsAttestationType expectedAType = IdsAttestationType.BASIC; - private int expectedAttestationMask = 0; + private Certificate localCertificate; + @NonNull + private URI ttpUri; + @NonNull + private IdsAttestationType expectedAType = IdsAttestationType.BASIC; + private int expectedAttestationMask = 0; - private TPM2dVerifierConfig() { - try { - ttpUri = new URI("https://invalid-ttp-uri/rat-verify"); - } catch (URISyntaxException e) { - throw new RuntimeException(e); + private TPM2dVerifierConfig() { + try { + ttpUri = new URI("https://invalid-ttp-uri/rat-verify"); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } - } - public static class Builder { - private static final TPM2dVerifierConfig config = new TPM2dVerifierConfig(); + public static class Builder { + private static final TPM2dVerifierConfig config = new TPM2dVerifierConfig(); - @NonNull - public Builder setTtpUri(URI ttpUri) { - config.ttpUri = ttpUri; - return this; + @NonNull + public Builder setTtpUri(URI ttpUri) { + config.ttpUri = ttpUri; + return this; + } + + @NonNull + public Builder setLocalCertificate(Certificate localCert) { + config.localCertificate = localCert; + return this; + } + + @NonNull + public Builder setExpectedAttestationType(IdsAttestationType aType) { + config.expectedAType = aType; + return this; + } + + public Builder setExpectedAttestationMask(int mask) { + config.expectedAttestationMask = mask; + return this; + } + + public TPM2dVerifierConfig build() { + return config; + } } @NonNull - public Builder setLocalCertificate(Certificate localCert) { - config.localCertificate = localCert; - return this; + public URI getTtpUri() { + return ttpUri; } @NonNull - public Builder setExpectedAttestationType(IdsAttestationType aType) { - config.expectedAType = aType; - return this; + public IdsAttestationType getExpectedAType() { + return expectedAType; } - public Builder setExpectedAttestationMask(int mask) { - config.expectedAttestationMask = mask; - return this; + public Certificate getLocalCertificate() { + return localCertificate; } - public TPM2dVerifierConfig build() { - return config; + public int getExpectedAttestationMask() { + return expectedAttestationMask; } - } - - @NonNull - public URI getTtpUri() { - return ttpUri; - } - - @NonNull - public IdsAttestationType getExpectedAType() { - return expectedAType; - } - - public Certificate getLocalCertificate() { - return localCertificate; - } - - public int getExpectedAttestationMask() { - return expectedAttestationMask; - } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 47190ab5c..1a2500856 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -4,16 +4,16 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server.TLSServer; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import java.util.concurrent.CompletableFuture; /** @@ -24,40 +24,33 @@ public class NativeTLSDriver implements SecureChannelDriver { private static final Logger LOG = LoggerFactory.getLogger(NativeTLSDriver.class); - /* - * Asynchronous client connect to a TLS server + /** + * Performs an asynchronous client connect to a TLS server. */ @Override - public void connect(Idscp2Settings settings, Idscp2Callback callback) { + public void connect(Idscp2Settings settings, SecureChannelInitListener channelInitListener) { try { - TLSClient tlsClient = new TLSClient(settings, callback); + TLSClient tlsClient = new TLSClient(settings, channelInitListener); tlsClient.connect(settings.getHost(), settings.getServerPort()); - - } catch (IOException | NoSuchAlgorithmException | KeyManagementException e){ - - LOG.error("listen() failed. {}", e.getMessage()); - LOG.debug(Arrays.toString(e.getStackTrace())); - callback.secureChannelConnectHandler(null); + } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) { + LOG.error("Call to connect() has failed", e); + channelInitListener.onSecureChannel(null, null); } } - /* - * Starting TLS Server + /** + * Creates and starts a new TLS Server instance. * - * return null on failure + * @return The SecureServer instance + * @throws Idscp2Exception If any error occurred during server creation/start */ @Override - public SecureServer listen(Idscp2Settings settings, Idscp2Callback configCallback, - CompletableFuture connectionPromise) { + public SecureServer listen(Idscp2Settings settings, SecureChannelInitListener channelInitListener, + CompletableFuture serverListenerPromise) { try { - TLSServer tlsServer = new TLSServer(settings, configCallback, connectionPromise); - tlsServer.start(); - return tlsServer; - - } catch (IOException | NoSuchAlgorithmException | KeyManagementException e){ - LOG.error("listen() failed.", e); + return new TLSServer(settings, channelInitListener, serverListenerPromise); + } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) { + throw new Idscp2Exception("Error while trying to to start SecureServer", e); } - - return null; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSConstants.java new file mode 100644 index 000000000..0e2e66c85 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSConstants.java @@ -0,0 +1,67 @@ +package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; + +/** + * TLS Constants + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public final class TLSConstants { + + // Used TLS version + public static final String TLS_INSTANCE = "TLSv1.3"; + + // Enabled encryption protocols + public static final String[] TLS_ENABLED_PROTOCOLS = { TLS_INSTANCE }; + + // Acceptable TLS ciphers + public static final String[] TLS_ENABLED_CIPHERS = { +// "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_RSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_RSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", +// "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" + }; + + private TLSConstants() { + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java index 9a3952894..78679508d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TLSSessionVerificationHelper.java @@ -20,186 +20,186 @@ * @author Leon Beckmann (leon.beckmannn@aisec.fraunhofer.de) */ public class TLSSessionVerificationHelper { - private static final Logger LOG = LoggerFactory.getLogger(TLSSessionVerificationHelper.class); - - private static final String ipv4Pattern = - "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; - private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}"; - - /* - * Checks if the ssl session is valid and the remote host can be trusted - * - * Due to the fact, that hostname verification is not specified in the secure socket layer, - * we have to check if the connected hostname matches to the subject of the peer certificate to - * avoid Man-In-The-Middle Attacks. This is required for every raw tls! - * - * Further we check the peer certificate validity to avoid the case that some of the certificates - * in our local trust_store are not valid anymore and allow a peer connector to connect with an - * expired certificate - * - * Throws SSlPeerUnverifiedException if peer certificate is not secure for this peer - */ - public static void verifyTlsSession(SSLSession sslSession) throws SSLPeerUnverifiedException{ - - String host = sslSession.getPeerHost(); - - LOG.debug("Connected to {}:{}", host, sslSession.getPeerPort()); - try { - - //get certificate - Certificate[] certificates = sslSession.getPeerCertificates(); - if (certificates.length != 1) { - throw new SSLPeerUnverifiedException("Unexpected number of certificates"); - } - X509Certificate peerCert = (X509Certificate) certificates[0]; - - /* - * According to RFC6125, hostname verification should be done against the certificate's - * subject alternative name's (SANs) dNSName field or the SANs IPAddress. In some legacy - * implementations, the check is done against the certificate's commonName, but this is - * deprecated for quite a while and is therefore not supported anymore in te IDSCP2 protocol. - */ - Collection> sans = peerCert.getSubjectAlternativeNames(); - if (sans == null) { - throw new SSLPeerUnverifiedException("No Subject alternative names for hostname " - + "verification provided"); - } - - ArrayList acceptedDnsNames = new ArrayList<>(); - ArrayList acceptedIpAddresses = new ArrayList<>(); - - for (List subjectAltName : sans) { - if (subjectAltName.size() != 2) { - continue; - } - Object value = subjectAltName.get(1); - switch ((Integer)subjectAltName.get(0)) { - case 2: //DNS_NAME - if (value instanceof String) { - acceptedDnsNames.add((String)value); - } else if (value instanceof byte[]) { - acceptedDnsNames.add(new String((byte[]) value)); + private static final Logger LOG = LoggerFactory.getLogger(TLSSessionVerificationHelper.class); + + private static final String ipv4Pattern = + "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])"; + private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}"; + + /* + * Checks if the ssl session is valid and the remote host can be trusted + * + * Due to the fact, that hostname verification is not specified in the secure socket layer, + * we have to check if the connected hostname matches to the subject of the peer certificate to + * avoid Man-In-The-Middle Attacks. This is required for every raw tls! + * + * Further we check the peer certificate validity to avoid the case that some of the certificates + * in our local trust_store are not valid anymore and allow a peer connector to connect with an + * expired certificate + * + * Throws SSlPeerUnverifiedException if peer certificate is not secure for this peer + */ + public static void verifyTlsSession(SSLSession sslSession) throws SSLPeerUnverifiedException { + + String host = sslSession.getPeerHost(); + + LOG.debug("Connected to {}:{}", host, sslSession.getPeerPort()); + try { + + //get certificate + Certificate[] certificates = sslSession.getPeerCertificates(); + if (certificates.length != 1) { + throw new SSLPeerUnverifiedException("Unexpected number of certificates"); } - break; - case 7: //IP_ADDRESS - if (value instanceof String) { - acceptedIpAddresses.add((String)value); - } else if (value instanceof byte[]) { - acceptedIpAddresses.add(new String((byte[]) value)); + X509Certificate peerCert = (X509Certificate) certificates[0]; + + /* + * According to RFC6125, hostname verification should be done against the certificate's + * subject alternative name's (SANs) dNSName field or the SANs IPAddress. In some legacy + * implementations, the check is done against the certificate's commonName, but this is + * deprecated for quite a while and is therefore not supported anymore in te IDSCP2 protocol. + */ + Collection> sans = peerCert.getSubjectAlternativeNames(); + if (sans == null) { + throw new SSLPeerUnverifiedException("No Subject alternative names for hostname " + + "verification provided"); } - break; - case 0: //OTHER_NAME - Not Supported - case 1: //RFC_822_Name - Not Supported - case 3: //X400_ADDRESS - Not Supported - case 4: //DIRECTORY_NAME - Not Supported - case 5: //EDI_PARTY_NAME - Not supported - case 6: //URI - Not Supported - case 8: //REGISTERED_ID - Not Supported - default: //unspecified General Name - should never happen - break; - } - } - - //toDo localhost is matched manually to 127.0.0.1 for testing.. - // automatic dns resolving via DNS service is not an option since we cannot trust the DNS - if (acceptedDnsNames.contains("localhost")) { - acceptedIpAddresses.add("127.0.0.1"); - } - - - if (isIpAddress(host)) { - //FIXME The server should provide a possibility to validate clients dnsNames against SANs in - // Client certificate to avoid MITMs. This is an open issue - //check ip addresses RFC 2818 (Section 3.1) - if (!acceptedIpAddresses.contains(host)) { - throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " - + "not belong to peer host"); - } - } else { - //check hostname - String[] hostLabels = host.split("\\."); - boolean found = false; - - for (String entry : acceptedDnsNames) { - if (checkHostname(entry.split("\\.", -1), hostLabels)) { - found = true; - break; - } - } - if (!found) { - throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " - + "not belong to peer host"); - } - } + ArrayList acceptedDnsNames = new ArrayList<>(); + ArrayList acceptedIpAddresses = new ArrayList<>(); + + for (List subjectAltName : sans) { + if (subjectAltName.size() != 2) { + continue; + } + Object value = subjectAltName.get(1); + switch ((Integer) subjectAltName.get(0)) { + case 2: //DNS_NAME + if (value instanceof String) { + acceptedDnsNames.add((String) value); + } else if (value instanceof byte[]) { + acceptedDnsNames.add(new String((byte[]) value)); + } + break; + case 7: //IP_ADDRESS + if (value instanceof String) { + acceptedIpAddresses.add((String) value); + } else if (value instanceof byte[]) { + acceptedIpAddresses.add(new String((byte[]) value)); + } + break; + case 0: //OTHER_NAME - Not Supported + case 1: //RFC_822_Name - Not Supported + case 3: //X400_ADDRESS - Not Supported + case 4: //DIRECTORY_NAME - Not Supported + case 5: //EDI_PARTY_NAME - Not supported + case 6: //URI - Not Supported + case 8: //REGISTERED_ID - Not Supported + default: //unspecified General Name - should never happen + break; + } + } + //toDo localhost is matched manually to 127.0.0.1 for testing.. + // automatic dns resolving via DNS service is not an option since we cannot trust the DNS + if (acceptedDnsNames.contains("localhost")) { + acceptedIpAddresses.add("127.0.0.1"); + } - //check certificate validity for now and at least one day - Date oneDay = new Date(); - oneDay.setTime(oneDay.getTime() + 86400000); - peerCert.checkValidity(); - peerCert.checkValidity(oneDay); + if (isIpAddress(host)) { + //FIXME The server should provide a possibility to validate clients dnsNames against SANs in + // Client certificate to avoid MITMs. This is an open issue + //check ip addresses RFC 2818 (Section 3.1) + if (!acceptedIpAddresses.contains(host)) { + throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " + + "not belong to peer host"); + } + } else { + //check hostname + String[] hostLabels = host.split("\\."); + boolean found = false; + + for (String entry : acceptedDnsNames) { + if (checkHostname(entry.split("\\.", -1), hostLabels)) { + found = true; + break; + } + } + + if (!found) { + throw new SSLPeerUnverifiedException("Hostname verification failed. Peer certificate does " + + "not belong to peer host"); + } + } - } catch (CertificateParsingException | CertificateNotYetValidException | - CertificateExpiredException e) { - throw new SSLPeerUnverifiedException("TLS Session Verification failed "+ e); - } - } + //check certificate validity for now and at least one day + Date oneDay = new Date(); + oneDay.setTime(oneDay.getTime() + 86400000); - /* - * check if host is an IP Address - */ - private static boolean isIpAddress(String host){ + peerCert.checkValidity(); + peerCert.checkValidity(oneDay); - Matcher ip4 = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE).matcher(host); - if (ip4.matches()) { - return true; + } catch (CertificateParsingException | CertificateNotYetValidException | + CertificateExpiredException e) { + throw new SSLPeerUnverifiedException("TLS Session Verification failed " + e); + } } - Matcher ip6 = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE).matcher(host); - return ip6.matches(); - } - - /* - * match dNS Name - */ - private static boolean checkHostname(String[] dnsNameLabels, String[] hostNameLabels) { /* - * support wildcard matching of DNS names as described in RFC6125 Section 6.4.3 - * - * Rules: - * 1. The client SHOULD NOT attempt to match a presented identifier in which the wildcard - * character comprises a label other than the left-most label - * (e.g., do not match bar.*.example.net). - * - * 2. If the wildcard character is the only character of the left-most label in the - * presented identifier, the client SHOULD NOT compare against anything but the left-most - * label of the reference identifier (e.g., *.example.com would match foo.example.com but - * not bar.foo.example.com or example.com). - * - * 3. The client MAY match a presented identifier in which the wildcard character is not the - * only character of the label (e.g., baz*.example.net and *baz.example.net and - * b*z.example.net would be taken to match baz1.example.net and foobaz.example.net and - * buzz.example.net, respectively). However, the client SHOULD NOT attempt to match a - * presented identifier where the wildcard character is embedded within an A-label or - * U-label of an internationalized domain name. + * check if host is an IP Address */ - if (dnsNameLabels.length == hostNameLabels.length) { //include rule 2 - //all labels without the first one must match completely (rule 1) - for (int i = 1; i < dnsNameLabels.length; i++) { - if (!dnsNameLabels[i].equals(hostNameLabels[i])) { - return false; + private static boolean isIpAddress(String host) { + + Matcher ip4 = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE).matcher(host); + if (ip4.matches()) { + return true; } - } - //first label could include wildcard character '*' (rule 1+3) - return hostNameLabels[0].matches(dnsNameLabels[0].replace("*", ".*")); + Matcher ip6 = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE).matcher(host); + return ip6.matches(); } - return false; - } + /* + * match dNS Name + */ + private static boolean checkHostname(String[] dnsNameLabels, String[] hostNameLabels) { + + /* + * support wildcard matching of DNS names as described in RFC6125 Section 6.4.3 + * + * Rules: + * 1. The client SHOULD NOT attempt to match a presented identifier in which the wildcard + * character comprises a label other than the left-most label + * (e.g., do not match bar.*.example.net). + * + * 2. If the wildcard character is the only character of the left-most label in the + * presented identifier, the client SHOULD NOT compare against anything but the left-most + * label of the reference identifier (e.g., *.example.com would match foo.example.com but + * not bar.foo.example.com or example.com). + * + * 3. The client MAY match a presented identifier in which the wildcard character is not the + * only character of the label (e.g., baz*.example.net and *baz.example.net and + * b*z.example.net would be taken to match baz1.example.net and foobaz.example.net and + * buzz.example.net, respectively). However, the client SHOULD NOT attempt to match a + * presented identifier where the wildcard character is embedded within an A-label or + * U-label of an internationalized domain name. + */ + if (dnsNameLabels.length == hostNameLabels.length) { //include rule 2 + //all labels without the first one must match completely (rule 1) + for (int i = 1; i < dnsNameLabels.length; i++) { + if (!dnsNameLabels[i].equals(hostNameLabels[i])) { + return false; + } + } + + //first label could include wildcard character '*' (rule 1+3) + return hostNameLabels[0].matches(dnsNameLabels[0].replace("*", ".*")); + } + + return false; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java deleted file mode 100644 index bbbec4b60..000000000 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/TlsConstants.java +++ /dev/null @@ -1,117 +0,0 @@ -package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel; - -/** - * TLS Constants - * - * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) - */ -public final class TlsConstants { - - public static final String END_OF_STREAM = "End of stream"; - - /* TLS specific settings */ - - //socket instances - public static final String TLS_INSTANCE = "TLSv1.3"; - - //enabled protocols - public static final String[] TLS_ENABLED_PROTOCOLS = {TLS_INSTANCE}; - - //enabled ciphers (only uncommented ciphers are activated) - public static final String[] TLS_ENABLED_CIPHER_TLS12 = { - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", - /*"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ - }; - - // not all of the enabled ciphers are supported by openssl yet - public static final String[] TLS_ENABLED_CIPHER_TLS13 = { - //"TLS_AES_128_GCM_SHA256", - "TLS_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", - /*"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",*/ - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", - /*"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"*/ - }; - - private TlsConstants() {} -} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java index 6249c795e..c0101dcf3 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; /** - * An interface for DataAvailableListeners, that will be notified when new data were received + * An interface for DataAvailableListeners, that will be notified when new data has been received * at the sslSocket * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index e3f60a084..3874c8c8f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -8,7 +8,7 @@ /** * A simple Listener thread that listens to an input stream and notifies a listeners - * when new data were received + * when new data has been received * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -18,16 +18,16 @@ public class InputListenerThread extends Thread implements InputListener { private DataAvailableListener listener = null; //no race conditions, could be empty list private volatile boolean running = true; - public InputListenerThread(InputStream in){ + public InputListenerThread(InputStream in) { this.in = new DataInputStream(in); } /* * Run the input listener thread that reads from wire and provides data to upper layer */ - public void run(){ + public void run() { byte[] buf; - while (running){ + while (running) { try { //first read the length int len = in.readInt(); @@ -38,7 +38,7 @@ public void run(){ this.listener.onMessage(buf); } catch (SocketTimeoutException ignore) { //timeout to catch safeStop() call - } catch (EOFException e){ + } catch (EOFException e) { listener.onClose(); running = false; //terminate } catch (IOException e) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index b3c16f91e..dfead2cbe 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -1,10 +1,10 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -18,7 +18,7 @@ import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CompletableFuture; /** * A TLS Client that notifies an Idscp2Configuration when a secure channel was created and the @@ -34,62 +34,61 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private final Socket clientSocket; private DataOutputStream out; private InputListenerThread inputListenerThread; - private SecureChannelListener listener; //race conditions are avoided using CountDownLatch - private final CountDownLatch listenerLatch = new CountDownLatch(1); - private final Idscp2Callback callback; + private final CompletableFuture listenerPromise = new CompletableFuture<>(); + private final SecureChannelInitListener secureChannelInitListener; + public TLSClient(Idscp2Settings clientSettings, SecureChannelInitListener secureChannelInitListener) + throws IOException, KeyManagementException, NoSuchAlgorithmException { + this.secureChannelInitListener = secureChannelInitListener; - public TLSClient(Idscp2Settings clientSettings, Idscp2Callback callback) - throws IOException, KeyManagementException, NoSuchAlgorithmException{ - this.callback = callback; - /* init TLS Client */ + // init TLS Client - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ + // get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables + // hostVerification and algorithm constraints TrustManager[] myTrustManager = PreConfiguration.getX509ExtTrustManager( clientSettings.getTrustStorePath(), clientSettings.getTrustStorePassword() ); - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ + // get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables + // connection specific key selection via key alias KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( clientSettings.getKeyStorePath(), clientSettings.getKeyStorePassword(), - clientSettings.getCertAlias(), + clientSettings.getCertificateAlias(), clientSettings.getKeyStoreKeyType() ); - SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + SSLContext sslContext = SSLContext.getInstance(TLSConstants.TLS_INSTANCE); sslContext.init(myKeyManager, myTrustManager, null); SSLSocketFactory socketFactory = sslContext.getSocketFactory(); - //create server socket + // create server socket clientSocket = socketFactory.createSocket(); SSLSocket sslSocket = (SSLSocket) clientSocket; - //set TLS constraints + // set TLS constraints SSLParameters sslParameters = sslSocket.getSSLParameters(); - sslParameters.setUseCipherSuitesOrder(false); //use server priority order + sslParameters.setUseCipherSuitesOrder(false); // use server priority order sslParameters.setNeedClientAuth(true); - sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 - sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher - //sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); is done in application layer + sslParameters.setProtocols(TLSConstants.TLS_ENABLED_PROTOCOLS); // only TLSv1.3 + sslParameters.setCipherSuites(TLSConstants.TLS_ENABLED_CIPHERS); // only allow strong cipher +// sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); // is done in application layer sslSocket.setSSLParameters(sslParameters); LOG.debug("TLS Client was initialized successfully"); } - /* + /** * Connect to TLS server and start TLS Handshake */ - public void connect(String hostname, int port){ + public void connect(String hostname, int port) { SSLSocket sslSocket = (SSLSocket) clientSocket; - if (sslSocket == null || sslSocket.isClosed()){ + if (sslSocket == null || sslSocket.isClosed()) { LOG.warn("Client socket is not available"); - callback.secureChannelConnectHandler(null); + secureChannelInitListener.onSecureChannel(null, null); return; } @@ -111,25 +110,25 @@ public void connect(String hostname, int port){ sslSocket.addHandshakeCompletedListener(this); LOG.debug("Start TLS Handshake"); sslSocket.startHandshake(); - } catch (SSLHandshakeException | SSLProtocolException e){ + } catch (SSLHandshakeException | SSLProtocolException e) { LOG.warn("TLS Handshake failed: {}", e.getMessage()); disconnect(); - callback.secureChannelConnectHandler(null); + secureChannelInitListener.onSecureChannel(null, null); } catch (IOException e) { LOG.error("Connecting TLS client to server failed " + e.getMessage()); disconnect(); - callback.secureChannelConnectHandler(null); + secureChannelInitListener.onSecureChannel(null, null); } } - private void disconnect(){ + private void disconnect() { LOG.debug("Disconnecting from tls server"); //close listener if (inputListenerThread != null && inputListenerThread.isAlive()) { inputListenerThread.safeStop(); } - if (clientSocket != null && !clientSocket.isClosed()){ + if (clientSocket != null && !clientSocket.isClosed()) { try { clientSocket.close(); } catch (IOException e) { @@ -139,23 +138,13 @@ private void disconnect(){ } @Override - public void onClose(){ - try { - listenerLatch.await(); - listener.onClose(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + public void onClose() { + listenerPromise.thenAccept(SecureChannelListener::onClose); } @Override - public void onError(){ - try { - listenerLatch.await(); - listener.onError(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + public void onError() { + listenerPromise.thenAccept(SecureChannelListener::onError); } @Override @@ -164,8 +153,8 @@ public void close() { } @Override - public boolean send(byte[] data){ - if (!isConnected()){ + public boolean send(byte[] data) { + if (!isConnected()) { LOG.error("Client cannot send data because socket is not connected"); return false; } else { @@ -175,14 +164,14 @@ public boolean send(byte[] data){ out.flush(); LOG.debug("Send message"); return true; - } catch (IOException e){ + } catch (IOException e) { LOG.error("Client cannot send data"); return false; } } } - public boolean isConnected(){ + public boolean isConnected() { return clientSocket != null && clientSocket.isConnected(); } @@ -202,27 +191,19 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) LOG.warn("TLS session is not valid. Close TLS connection", e); } disconnect(); - callback.secureChannelConnectHandler(null); + secureChannelInitListener.onSecureChannel(null, null); return; } - //Create secure channel, register secure channel as message listener and provide it to - // IDSCP2 Configuration. - //Start Input Listener + // Create secure channel, register secure channel as message listener and notify IDSCP2 Configuration. SecureChannel secureChannel = new SecureChannel(this); - this.listener = secureChannel; - listenerLatch.countDown(); + this.listenerPromise.complete(secureChannel); inputListenerThread.start(); - callback.secureChannelConnectHandler(secureChannel); + secureChannelInitListener.onSecureChannel(secureChannel, null); } @Override public void onMessage(byte[] data) { - try{ - listenerLatch.await(); - listener.onMessage(data); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } + listenerPromise.thenAccept(listener -> listener.onMessage(data)); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 17bba4e93..254d3f328 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -1,17 +1,18 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TlsConstants; +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSConstants; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.io.IOException; import java.net.ServerSocket; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -23,117 +24,131 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TLSServer extends Thread implements SecureServer { +public class TLSServer implements Runnable, SecureServer { private static final Logger LOG = LoggerFactory.getLogger(TLSServer.class); private volatile boolean isRunning = false; private final ServerSocket serverSocket; - private final Idscp2Callback idscpConfigCallback; //no race conditions - private final CompletableFuture connectionPromise; + private final SecureChannelInitListener secureChannelInitListener; + private final CompletableFuture serverListenerPromise; + private final Thread serverThread; - public TLSServer(Idscp2Settings serverSettings, Idscp2Callback configCallback, - CompletableFuture connectionPromise) + public TLSServer(Idscp2Settings serverSettings, SecureChannelInitListener secureChannelInitListener, + CompletableFuture serverListenerPromise) throws IOException, NoSuchAlgorithmException, KeyManagementException { - this.idscpConfigCallback = configCallback; - this.connectionPromise = connectionPromise; + this.secureChannelInitListener = secureChannelInitListener; + this.serverListenerPromise = serverListenerPromise; /* init server for TCP/TLS communication */ - /* get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, which enables - * hostVerification and algorithm constraints */ - LOG.debug("Create trust manager for tls server"); + // Get array of TrustManagers, that contains only one instance of X509ExtendedTrustManager, + // which enables host verification and algorithm constraints + LOG.debug("Creating trust manager for TLS server..."); TrustManager[] myTrustManager = PreConfiguration.getX509ExtTrustManager( serverSettings.getTrustStorePath(), serverSettings.getTrustStorePassword() ); - /* get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables - * connection specific key selection via key alias*/ - LOG.debug("Create key manager for tls server"); + // Get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, + // which enables connection specific key selection via key alias + LOG.debug("Creating key manager for TLS server..."); KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( serverSettings.getKeyStorePath(), serverSettings.getKeyStorePassword(), - serverSettings.getCertAlias(), + serverSettings.getCertificateAlias(), serverSettings.getKeyStoreKeyType() ); - LOG.debug("Set tls security attributes and create tls server socket"); - - // create tls context based on keyManager and trustManager - SSLContext sslContext = SSLContext.getInstance(TlsConstants.TLS_INSTANCE); + LOG.debug("Setting TLS security attributes and creating TLS server socket..."); + // Create TLS context based on keyManager and trustManager + SSLContext sslContext = SSLContext.getInstance(TLSConstants.TLS_INSTANCE); sslContext.init(myKeyManager, myTrustManager, null); SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory(); - //create server socket - serverSocket = socketFactory.createServerSocket(serverSettings.getServerPort()); - //set timeout for serverSocket.accept() to allow safeStop() + serverSocket = socketFactory.createServerSocket(serverSettings.getServerPort()); + // Set timeout for serverSocket.accept() serverSocket.setSoTimeout(5000); SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocket; - //set tls constraints + // Set TLS constraints SSLParameters sslParameters = sslServerSocket.getSSLParameters(); sslParameters.setUseCipherSuitesOrder(true); //server determines priority-order of algorithms in CipherSuite sslParameters.setNeedClientAuth(true); //client must authenticate - sslParameters.setProtocols(TlsConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 - sslParameters.setCipherSuites(TlsConstants.TLS_ENABLED_CIPHER_TLS13); //only allow strong cipher suite + sslParameters.setProtocols(TLSConstants.TLS_ENABLED_PROTOCOLS); //only TLSv1.3 + sslParameters.setCipherSuites(TLSConstants.TLS_ENABLED_CIPHERS); //only allow strong cipher suite sslServerSocket.setSSLParameters(sslParameters); - LOG.debug("TLS server was initialized successfully"); + + LOG.debug("Starting TLS server..."); + serverThread = new Thread(this, "TLS Server Thread " + + serverSettings.getHost() + ":" + serverSettings.getServerPort()); + serverThread.start(); } @Override - public void run(){ - LOG.debug("Starting tls server"); - - if (serverSocket == null || serverSocket.isClosed()){ - LOG.error("TLS Server socket is not available"); + public void run() { + final ServerSocket serverSocket; + if ((serverSocket = this.serverSocket) == null || serverSocket.isClosed()) { + LOG.error("ServerSocket is not available, server thread is stopping now."); return; } - SSLSocket sslSocket; isRunning = true; - LOG.debug("TLS server is running"); - while(isRunning){ + LOG.debug("TLS server started, entering accept() loop..."); + while (isRunning) { try { - sslSocket = (SSLSocket) serverSocket.accept(); - } catch (SocketTimeoutException e){ + final var sslSocket = (SSLSocket) serverSocket.accept(); + try { + // Start new server thread + LOG.debug("New TLS client has connected. Creating new server thread..."); + final var serverThread = new TLSServerThread(sslSocket, secureChannelInitListener, serverListenerPromise); + sslSocket.addHandshakeCompletedListener(serverThread); + serverThread.start(); + } catch (Exception serverThreadException) { + LOG.error("Error whilst creating/starting TLSServerThread", serverThreadException); + } + } catch (SocketTimeoutException e) { //timeout on serverSocket blocking functions was reached //in this way we can catch safeStop() function, that makes isRunning false //without closing the serverSocket, so we can stop and restart the server //alternative: close serverSocket. But then we cannot reuse it - continue; + } catch (SocketException e) { + LOG.debug("Server socket has been closed."); + isRunning = false; } catch (IOException e) { - LOG.error("TLS Server failed"); - e.printStackTrace(); + LOG.error("TLS server socket accept failed", e); isRunning = false; - return; } - - //start new server thread - LOG.debug("New TLS client has connected. Create new server session"); - TLSServerThread server = new TLSServerThread(sslSocket, idscpConfigCallback, connectionPromise); - sslSocket.addHandshakeCompletedListener(server); - server.start(); } - if (!serverSocket.isClosed()){ + if (!serverSocket.isClosed()) { try { serverSocket.close(); } catch (IOException e) { - LOG.warn("Could not close TLS server socket"); - e.printStackTrace(); + LOG.warn("Could not close TLS server socket", e); } } } @Override - public void safeStop(){ + public void safeStop() { LOG.debug("Stopping tls server"); isRunning = false; +// try { +// serverSocket.close(); +// } catch (IOException e) { +// LOG.warn("Trying to close server socket failed!", e); +// } + try { + this.serverThread.join(); + } catch (InterruptedException e) { + LOG.warn("InterruptedException whilst waiting for server stop", e); + Thread.currentThread().interrupt(); + } } @Override - public boolean isRunning(){ + public boolean isRunning() { return isRunning; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index e82c35c33..b513d0989 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -1,8 +1,9 @@ package de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.idscp_core.FastLatch; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -13,89 +14,69 @@ import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSocket; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.EOFException; -import java.io.IOException; +import java.io.*; import java.net.SocketTimeoutException; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; /** * A TLSServerThread that notifies an IDSCP2Config when a secure channel was created and the * TLS handshake is done - * + *

* When new data are available the serverThread transfers it to the SecureChannelListener * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TLSServerThread extends Thread implements HandshakeCompletedListener, SecureChannelEndpoint { +public class TLSServerThread extends Thread implements HandshakeCompletedListener, SecureChannelEndpoint, Closeable { private static final Logger LOG = LoggerFactory.getLogger(TLSServerThread.class); - private final SSLSocket sslSocket; private volatile boolean running = true; - private DataInputStream in; - private DataOutputStream out; - private SecureChannelListener listener = null; // race conditions are avoided using CountDownLatch - private final Idscp2Callback configCallback; - private final CompletableFuture connectionPromise; - private final CountDownLatch listenerLatch = new CountDownLatch(1); - private final CountDownLatch tlsVerificationLatch = new CountDownLatch(1); - + private final DataInputStream in; + private final DataOutputStream out; + private final SSLSocket sslSocket; + private final SecureChannelInitListener configCallback; + private final CompletableFuture serverListenerPromise; + private final CompletableFuture channelListenerPromise = new CompletableFuture<>(); + private final FastLatch tlsVerificationLatch = new FastLatch(); - TLSServerThread(SSLSocket sslSocket, Idscp2Callback configCallback, - CompletableFuture connectionPromise){ + TLSServerThread(SSLSocket sslSocket, SecureChannelInitListener configCallback, + CompletableFuture serverListenerPromise) throws IOException { this.sslSocket = sslSocket; this.configCallback = configCallback; - this.connectionPromise = connectionPromise; - - try { - //set timout for blocking read - sslSocket.setSoTimeout(5000); - in = new DataInputStream(sslSocket.getInputStream()); - out = new DataOutputStream(sslSocket.getOutputStream()); - } catch (IOException e){ - LOG.error(e.getMessage()); - running = false; - } + this.serverListenerPromise = serverListenerPromise; + // Set timeout for blocking read + sslSocket.setSoTimeout(5000); + in = new DataInputStream(sslSocket.getInputStream()); + out = new DataOutputStream(sslSocket.getOutputStream()); } @Override - public void run(){ + public void run() { // first run the tls handshake to enforce catching every error occurred during the handshake // before reading from buffer. Else if there exists any non-catched exception during handshake // the thread would wait forever in onError() until handshakeCompleteListener is called try { sslSocket.startHandshake(); - //wait for tls session verification - while (true) { - try { - tlsVerificationLatch.await(); - break; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } + // Wait for TLS session verification + tlsVerificationLatch.await(); } catch (IOException e) { - LOG.warn("SSLHandshakeException occurred. Quit server session", e); + LOG.warn("Exception occurred during SSL handshake. Quiting server thread...", e); running = false; } //wait for new data while running byte[] buf; - while (running){ + while (running) { try { int len = in.readInt(); buf = new byte[len]; in.readFully(buf, 0, len); onMessage(buf); - } catch (SocketTimeoutException ignore) { - //timeout catches safeStop() call and allows to send server_goodbye - } catch (EOFException e){ + // Timeout catches safeStop() call and allows to send server_goodbye + } catch (EOFException e) { onClose(); running = false; - } catch (IOException e){ + } catch (IOException e) { onError(); running = false; } @@ -103,17 +84,18 @@ public void run(){ closeSockets(); } - private void closeSockets(){ + private void closeSockets() { try { out.close(); in.close(); sslSocket.close(); - } catch (IOException ignore) {} + } catch (IOException ignore) { + } } @Override public boolean send(byte[] data) { - if (!isConnected()){ + if (!isConnected()) { LOG.error("Server cannot send data because socket is not connected"); closeSockets(); return false; @@ -122,9 +104,9 @@ public boolean send(byte[] data) { out.writeInt(data.length); out.write(data); out.flush(); - LOG.debug("Send message: " + new String(data)); + LOG.trace("Send message: " + new String(data)); return true; - } catch (IOException e){ + } catch (IOException e) { LOG.error("ServerThread cannot send data."); closeSockets(); return false; @@ -132,22 +114,12 @@ public boolean send(byte[] data) { } } - private void onClose(){ - try { - listenerLatch.await(); - listener.onClose(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + private void onClose() { + channelListenerPromise.thenAccept(SecureChannelListener::onClose); } - private void onError(){ - try { - listenerLatch.await(); - listener.onError(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + private void onError() { + channelListenerPromise.thenAccept(SecureChannelListener::onError); } @Override @@ -156,16 +128,11 @@ public void close() { } @Override - public void onMessage(byte[] data) { - try{ - listenerLatch.await(); - this.listener.onMessage(data); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } + public void onMessage(byte[] data) { + channelListenerPromise.thenAccept(listener -> listener.onMessage(data)); } - private void safeStop(){ + private void safeStop() { running = false; } @@ -183,20 +150,19 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) try { TLSSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); LOG.debug("TLS session is valid"); - tlsVerificationLatch.countDown(); } catch (SSLPeerUnverifiedException e) { if (LOG.isWarnEnabled()) { LOG.warn("TLS session is not valid. Close TLS connection", e); } - running = false; //set running false before tlsVerificationLatch is decremented - tlsVerificationLatch.countDown(); + running = false; // set running false before tlsVerificationLatch is decremented return; + } finally { + tlsVerificationLatch.unlock(); } //provide secure channel to IDSCP2 Config and register secure channel as listener SecureChannel secureChannel = new SecureChannel(this); - this.listener = secureChannel; - listenerLatch.countDown(); - configCallback.secureChannelListenHandler(secureChannel, connectionPromise); + this.channelListenerPromise.complete(secureChannel); + configCallback.onSecureChannel(secureChannel, serverListenerPromise); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java index e26bc966a..28e834095 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatProverDriver.java @@ -10,7 +10,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public abstract class RatProverDriver extends Thread{ +public abstract class RatProverDriver extends Thread { private static final Logger LOG = LoggerFactory.getLogger(RatProverDriver.class); protected boolean running = true; @@ -19,7 +19,8 @@ public abstract class RatProverDriver extends Thread{ /* * Delegate an IDSCP2 message to the RatProver driver */ - public void delegate(byte[] message){} + public void delegate(byte[] message) { + } /* * Terminate and cancel the RatProver driver @@ -29,11 +30,11 @@ public void terminate() { this.interrupt(); } - public void setListener(FsmListener listener){ + public void setListener(FsmListener listener) { fsmListener = listener; } - public void setConfig(Object config){ + public void setConfig(Object config) { LOG.warn("Method 'setConfig' for RatProverDriver is not implemented"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java index 79686cda7..52d269c9f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/RatVerifierDriver.java @@ -10,7 +10,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public abstract class RatVerifierDriver extends Thread{ +public abstract class RatVerifierDriver extends Thread { private static final Logger LOG = LoggerFactory.getLogger(RatVerifierDriver.class); protected boolean running = true; @@ -19,7 +19,8 @@ public abstract class RatVerifierDriver extends Thread{ /* * Delegate the IDSCP2 message to the RatVerifier driver */ - public void delegate(byte[] message){} + public void delegate(byte[] message) { + } /* * Terminate and cancel the RatVerifier driver @@ -29,7 +30,7 @@ public void terminate() { this.interrupt(); } - public void setListener(FsmListener listener){ + public void setListener(FsmListener listener) { fsmListener = listener; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 02a3f0d0d..09c8202cf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -1,8 +1,9 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Callback; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import java.util.concurrent.CompletableFuture; @@ -17,11 +18,11 @@ public interface SecureChannelDriver { /* * Asynchronous method to create a secure connection to a secure server */ - void connect(Idscp2Settings settings, Idscp2Callback configCallback); + void connect(Idscp2Settings settings, SecureChannelInitListener channelInitListener); /* * Starting a secure server */ - SecureServer listen(Idscp2Settings settings, Idscp2Callback configCallback, - CompletableFuture connectionPromise); + SecureServer listen(Idscp2Settings settings, SecureChannelInitListener channelInitListener, + CompletableFuture serverListenerPromise) throws Idscp2Exception; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java index 9c19390ea..cc3b10850 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/error/Idscp2Exception.java @@ -5,7 +5,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Idscp2Exception extends Exception{ +public class Idscp2Exception extends RuntimeException { public Idscp2Exception(String message) { super(message); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index ecf410568..dbf0223cb 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -13,81 +13,86 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; public class Idscp2ClientInitiator implements Idscp2EndpointListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ClientInitiator.class); - public void init(Idscp2Settings settings){ + public void init(Idscp2Settings settings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = - new DefaultDapsDriverConfig.Builder() - .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") - .setKeyStorePath(settings.getKeyStorePath()) - .setTrustStorePath(settings.getTrustStorePath()) - .setKeyStorePassword(settings.getKeyStorePassword()) - .setTrustStorePassword(settings.getTrustStorePassword()) - .setKeyAlias(settings.getDapsKeyAlias()) - .setDapsUrl("https://daps.aisec.fraunhofer.de") - .build(); + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(settings.getKeyStorePath()) + .setTrustStorePath(settings.getTrustStorePath()) + .setKeyStorePassword(settings.getKeyStorePassword()) + .setTrustStorePassword(settings.getTrustStorePassword()) + .setKeyAlias(settings.getDapsKeyAlias()) + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); RatProverDriverRegistry.getInstance().registerDriver( - "Dummy", RatProverDummy.class, null); + "Dummy", RatProverDummy.class, null); RatVerifierDriverRegistry.getInstance().registerDriver( - "Dummy", RatVerifierDummy.class, null); + "Dummy", RatVerifierDummy.class, null); RatProverDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dProver.class, - new TPM2dProverConfig.Builder().build() + "TPM2d", TPM2dProver.class, + new TPM2dProverConfig.Builder().build() ); RatVerifierDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dVerifier.class, - new TPM2dVerifierConfig.Builder().build() + "TPM2d", TPM2dVerifier.class, + new TPM2dVerifierConfig.Builder().build() ); Idscp2Configuration clientConfig = new Idscp2Configuration( - this, - dapsDriver, - secureChannelDriver, - settings.getExpectedAttestation(), - settings.getSupportedAttestation(), - settings.getRatTimeoutDelay() + this, + dapsDriver, + secureChannelDriver, + settings.getExpectedAttestation(), + settings.getSupportedAttestation(), + settings.getRatTimeoutDelay() ); clientConfig.connect(settings); } @Override public void onConnection(Idscp2Connection connection) { - System.out.println("Client: New connection with id " + connection.getConnectionId()); - connection.addConnectionListener(new Idscp2ConnectionListener() { + System.out.println("Client: New connection with id " + connection.getId()); + connection.addConnectionListener(new Idscp2ConnectionAdapter() { @Override public void onError(String error) { - System.out.println("Client connection error occurred: " + error); + LOG.error("Client connection error occurred: " + error); } @Override - public void onClose(String connectionId) { - System.out.println("Client: Connection with id " + connectionId + " has been closed"); + public void onClose(Idscp2Connection connection) { + LOG.info("Client: Connection with id " + connection.getId() + " has been closed"); } }); connection.addGenericMessageListener(((c, type, data) -> System.out.println( - "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); - // Register listener for server reply - connection.addMessageListener("pong", (c, type, data) -> - System.out.println("Received pong message: " + new String(data, StandardCharsets.UTF_8))); + "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); + connection.addMessageListener("ping", (c, type, data) -> { + System.out.println("Received ping message: " + new String(data, StandardCharsets.UTF_8)); + CompletableFuture.runAsync(c::close); // FSM error if run from the same thread + }); System.out.println("Sending PING..."); connection.send("ping", "PING".getBytes(StandardCharsets.UTF_8)); } @Override public void onError(String error) { - System.out.println("Client endpoint error occurred: " + error); + LOG.error("Client endpoint error occurred: " + error); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index a5d79ce94..b71befe88 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -12,98 +12,94 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; public class Idscp2ServerInitiator implements Idscp2EndpointListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerInitiator.class); - public void init(Idscp2Settings serverSettings) { + public void init(Idscp2Settings serverSettings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = - new DefaultDapsDriverConfig.Builder() - .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") - .setKeyStorePath(serverSettings.getKeyStorePath()) - .setTrustStorePath(serverSettings.getTrustStorePath()) - .setKeyStorePassword(serverSettings.getKeyStorePassword()) - .setTrustStorePassword(serverSettings.getTrustStorePassword()) - .setKeyAlias(serverSettings.getDapsKeyAlias()) - .setDapsUrl("https://daps.aisec.fraunhofer.de") - .build(); + new DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(serverSettings.getKeyStorePath()) + .setTrustStorePath(serverSettings.getTrustStorePath()) + .setKeyStorePassword(serverSettings.getKeyStorePassword()) + .setTrustStorePassword(serverSettings.getTrustStorePassword()) + .setKeyAlias(serverSettings.getDapsKeyAlias()) + .setDapsUrl("https://daps.aisec.fraunhofer.de") + .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); RatProverDriverRegistry.getInstance().registerDriver( - "Dummy", RatProverDummy.class, null); + "Dummy", RatProverDummy.class, null); RatVerifierDriverRegistry.getInstance().registerDriver( - "Dummy", RatVerifierDummy.class, null); + "Dummy", RatVerifierDummy.class, null); RatProverDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dProver.class, - new TPM2dProverConfig.Builder().build() + "TPM2d", TPM2dProver.class, + new TPM2dProverConfig.Builder().build() ); RatVerifierDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dVerifier.class, - new TPM2dVerifierConfig.Builder().build() + "TPM2d", TPM2dVerifier.class, + new TPM2dVerifierConfig.Builder().build() ); Idscp2Configuration idscpServerConfig = new Idscp2Configuration( - this, - dapsDriver, - secureChannelDriver, - serverSettings.getExpectedAttestation(), - serverSettings.getSupportedAttestation(), - serverSettings.getRatTimeoutDelay() + this, + dapsDriver, + secureChannelDriver, + serverSettings.getExpectedAttestation(), + serverSettings.getSupportedAttestation(), + serverSettings.getRatTimeoutDelay() ); - Idscp2Server idscp2Server; - try { - idscp2Server = idscpServerConfig.listen(serverSettings); - } catch (Idscp2Exception e) { - //e.printStackTrace(); - return; - } - //secureServer.safeStop(); + Idscp2Server idscp2Server = idscpServerConfig.listen(serverSettings); + try { - Thread.sleep(120000); //run server for 2 minutes - } catch (Exception e){ - return; + Thread.sleep(40_000); //run server for 2 minutes + } catch (Exception ignored) { + } finally { + idscp2Server.terminate(); } - idscp2Server.terminate(); } @Override public void onConnection(Idscp2Connection connection) { - System.out.println("Server: New connection with id " + connection.getConnectionId()); - connection.addConnectionListener(new Idscp2ConnectionListener() { + System.out.println("Server: New connection with id " + connection.getId()); + connection.addConnectionListener(new Idscp2ConnectionAdapter() { @Override public void onError(String error) { - System.out.println("Server connection error occurred: " + error); + LOG.error("Server connection error occurred: " + error); } @Override - public void onClose(String connectionId) { - System.out.println("Server: Connection with id " + connectionId + " has been closed"); + public void onClose(Idscp2Connection connection) { + LOG.info("Server: Connection with id " + connection.getId() + " has been closed"); } }); connection.addGenericMessageListener(((c, type, data) -> System.out.println( - "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); + "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); connection.addMessageListener("ping", ((c, type, data) -> { System.out.println("Received ping message:\n" + new String(data, StandardCharsets.UTF_8)); System.out.println("Sending PONG..."); - c.send("pong", "PONG".getBytes(StandardCharsets.UTF_8)); + c.send("ping", "PONG".getBytes(StandardCharsets.UTF_8)); })); } @Override public void onError(String error) { - System.out.println("Server endpoint error occurred: " + error); + LOG.error("Server endpoint error occurred: " + error); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java index c97741f93..3b1b52dbd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java @@ -5,17 +5,17 @@ public class RunTLSClient { - public static void main(String[] args){ + public static void main(String[] args) { //start client Idscp2Settings settings = new Idscp2Settings.Builder() - .setKeyStore(RunTLSClient.class.getClassLoader(). - getResource("ssl/aisecconnector1-keystore.jks").getPath()) - .setTrustStore(RunTLSClient.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()) - .setCertificateAlias("1.0.1") - .setDapsKeyAlias("1") - .setRatTimeoutDelay(10) - .build(); + .setKeyStorePath(RunTLSClient.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(RunTLSClient.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") + .setRatTimeoutDelay(300) + .build(); Idscp2ClientInitiator initiator = new Idscp2ClientInitiator(); initiator.init(settings); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java index 2816fb636..04812608f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java @@ -4,17 +4,17 @@ public class RunTLSServer { - public static void main(String[] argv){ + public static void main(String[] argv) { Idscp2Settings settings = new Idscp2Settings.Builder() - .setKeyStore(RunTLSClient.class.getClassLoader(). - getResource("ssl/aisecconnector1-keystore.jks").getPath()) - .setTrustStore(RunTLSServer.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()) - .setCertificateAlias("1.0.1") - .setDapsKeyAlias("1") - .setRatTimeoutDelay(14) - .build(); + .setKeyStorePath(RunTLSClient.class.getClassLoader(). + getResource("ssl/aisecconnector1-keystore.jks").getPath()) + .setTrustStorePath(RunTLSServer.class.getClassLoader(). + getResource("ssl/client-truststore_new.jks").getPath()) + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") + .setRatTimeoutDelay(300) + .build(); Idscp2ServerInitiator initiator = new Idscp2ServerInitiator(); initiator.init(settings); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/FastLatch.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/FastLatch.java new file mode 100644 index 000000000..13ec26836 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/FastLatch.java @@ -0,0 +1,50 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This latch implementation uses double-checked-locking, a concept that is mostly broken. + * However, double-checked locking does work for primitives that are atomic w.r.t. the memory model, + * see https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html + * It is assumed that the JVM implementation always handles byte vars atomically, + * otherwise the correctness of this code may be broken! + * + * @author Michael Lux (michael.lux@aisec.fraunhofer.de) + */ +public class FastLatch { + private static final Logger LOG = LoggerFactory.getLogger(FastLatch.class); + private byte locked = 1; + + /** + * Wait for this latch to be unlocked. + */ + public void await() { + // Check locked flag without synchronization, such that method returns immediately + // without synchronization overhead if unlocked. + while (locked != 0) { + synchronized (this) { + // Check the locked flag again to prevent eternal waiting if notifyAll() has been called + // before this critical section. + if (locked != 0) { + try { + wait(); + } catch (InterruptedException ie) { + LOG.warn("Ignored InterruptException, awaiting unlock...", ie); + } + } + } + } + } + + /** + * Unlocks this latch instance. + */ + public void unlock() { + synchronized (this) { + locked = 0; + notifyAll(); + } + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index 0546b40c6..4451794ce 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -18,28 +18,33 @@ public class Idscp2Connection { private final FSM fsm; private final String connectionId; - private final Set connectionListeners = new HashSet<>(); - private final Set genericMessageListeners = new HashSet<>(); + private final Set connectionListeners = Collections.synchronizedSet(new HashSet<>()); + private final Set genericMessageListeners = Collections.synchronizedSet(new HashSet<>()); private final Map> messageListeners = new HashMap<>(); + private final FastLatch messageLatch = new FastLatch(); public Idscp2Connection(FSM fsm, String connectionId) { this.fsm = fsm; this.connectionId = connectionId; } - /* + public void unlockMessaging() { + messageLatch.unlock(); + } + + /** * Close the idscp connection */ public void close() { - // unregister connection from the idscp server - synchronized (connectionListeners) { - connectionListeners.forEach(l -> l.onClose(connectionId)); + // Unregister connection from the server + if (fsm.isNotClosed()) { + connectionListeners.forEach(l -> l.onClose(this)); } fsm.terminate(); } - /* - * Send data to the peer idscp connector + /** + * Send data to the peer IDSCP2 connector */ public void send(String type, byte[] msg) { LOG.debug("Send data of type \"" + type + "\" "); @@ -47,10 +52,10 @@ public void send(String type, byte[] msg) { } public void onMessage(String type, byte[] msg) { + // When unlock is called, although not synchronized, this will eventually stop blocking. + messageLatch.await(); LOG.debug("Received new IDSCP Message: " + Arrays.toString(msg)); - synchronized (genericMessageListeners) { - genericMessageListeners.forEach(l -> l.onMessage(this, type, msg)); - } + genericMessageListeners.forEach(l -> l.onMessage(this, type, msg)); Set listeners = messageListeners.get(type); if (listeners != null) { //noinspection SynchronizationOnLocalVariableOrMethodParameter @@ -61,74 +66,66 @@ public void onMessage(String type, byte[] msg) { } public void onClose() { - LOG.debug("Connection with id {} has been closed, notify user", connectionId); - synchronized (connectionListeners) { - connectionListeners.forEach(l -> l.onClose(connectionId)); - } + LOG.debug("Connection with id {} has been closed, notify listeners", connectionId); + connectionListeners.forEach(l -> l.onClose(this)); } - /* + /** * Check if the idscp connection is currently established + * + * @return Connection established state */ + @SuppressWarnings("unused") public boolean isConnected() { return fsm.isConnected(); } - public String getConnectionId() { + public String getId() { return connectionId; } public void addConnectionListener(Idscp2ConnectionListener listener) { - synchronized (connectionListeners) { - connectionListeners.add(listener); - } + connectionListeners.add(listener); } + @SuppressWarnings("unused") public boolean removeConnectionListener(Idscp2ConnectionListener listener) { - synchronized (connectionListeners) { - return connectionListeners.remove(listener); - } + return connectionListeners.remove(listener); } public void addGenericMessageListener(Idscp2MessageListener listener) { - synchronized (genericMessageListeners) { - genericMessageListeners.add(listener); - } + genericMessageListeners.add(listener); } + @SuppressWarnings("UnusedReturnValue") public boolean removeGenericMessageListener(Idscp2MessageListener listener) { - synchronized (genericMessageListeners) { - return genericMessageListeners.remove(listener); - } + return genericMessageListeners.remove(listener); } public void addMessageListener(@Nullable String type, Idscp2MessageListener listener) { - synchronized (messageListeners) { - Set messageTypeListeners + Set messageTypeListeners = messageListeners.computeIfAbsent(type, k -> new HashSet<>()); - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized (messageTypeListeners) { - messageTypeListeners.add(listener); - } - messageListeners.put(type, messageTypeListeners); + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (messageTypeListeners) { + messageTypeListeners.add(listener); } + messageListeners.put(type, messageTypeListeners); } + @SuppressWarnings("unused") public boolean removeMessageListener(@Nullable String type, Idscp2MessageListener listener) { - synchronized (messageListeners) { - Set messageTypeListeners = messageListeners.get(type); - if (messageTypeListeners == null) { - return false; - } - final boolean ret; - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized (messageTypeListeners) { - ret = messageTypeListeners.remove(listener); - } - if (messageTypeListeners.isEmpty()) { - messageListeners.remove(type); - } - return ret; + Set messageTypeListeners = messageListeners.get(type); + if (messageTypeListeners == null) { + return false; + } + final boolean ret; + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (messageTypeListeners) { + ret = messageTypeListeners.remove(listener); + } + if (messageTypeListeners.isEmpty()) { + messageListeners.remove(type); } + return ret; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java new file mode 100644 index 000000000..9588fe687 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java @@ -0,0 +1,12 @@ +package de.fhg.aisec.ids.idscp2.idscp_core; + +public class Idscp2ConnectionAdapter implements Idscp2ConnectionListener { + + @Override + public void onError(String error) { + } + + @Override + public void onClose(Idscp2Connection connection) { + } +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java index 0441615d8..40bd19b1c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java @@ -8,5 +8,5 @@ public interface Idscp2ConnectionListener { void onError(String error); - void onClose(String connectionId); + void onClose(Idscp2Connection connection); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java index 1c038d099..658d0f1c1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2MessageHelper.java @@ -1,7 +1,7 @@ package de.fhg.aisec.ids.idscp2.idscp_core; import com.google.protobuf.ByteString; -import de.fhg.aisec.ids.messages.IDSCP2.*; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2.*; import java.util.Arrays; @@ -12,7 +12,7 @@ */ public class Idscp2MessageHelper { - public static IdscpMessage createIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite){ + public static IdscpMessage createIdscpHelloMessage(byte[] dat, String[] supportedRatSuite, String[] expectedRatSuite) { IdscpDat idscpDat = IdscpDat.newBuilder() .setToken(ByteString.copyFrom(dat)) .build(); @@ -29,7 +29,7 @@ public static IdscpMessage createIdscpHelloMessage(byte[] dat, String[] supporte .build(); } - public static IdscpMessage createIdscpCloseMessage(String closeMsg, IdscpClose.CloseCause causeCode){ + public static IdscpMessage createIdscpCloseMessage(String closeMsg, IdscpClose.CloseCause causeCode) { IdscpClose idscpClose = IdscpClose.newBuilder() .setCauseCode(causeCode) .setCauseMsg(closeMsg) @@ -40,13 +40,13 @@ public static IdscpMessage createIdscpCloseMessage(String closeMsg, IdscpClose.C .build(); } - public static IdscpMessage createIdscpDatExpiredMessage(){ + public static IdscpMessage createIdscpDatExpiredMessage() { return IdscpMessage.newBuilder() .setIdscpDatExpired(IdscpDatExpired.newBuilder().build()) .build(); } - public static IdscpMessage createIdscpDatMessage(byte[] dat){ + public static IdscpMessage createIdscpDatMessage(byte[] dat) { IdscpDat idscpDat = IdscpDat.newBuilder() .setToken(ByteString.copyFrom(dat)) .build(); @@ -56,7 +56,7 @@ public static IdscpMessage createIdscpDatMessage(byte[] dat){ .build(); } - public static IdscpMessage createIdscpReRatMessage(String cause){ + public static IdscpMessage createIdscpReRatMessage(String cause) { IdscpReRat idscpReRat = IdscpReRat.newBuilder() .setCause(cause) .build(); @@ -89,20 +89,20 @@ public static IdscpMessage createIdscpDataMessage(String type, byte[] data) { return createIdscpDataMessage(type, null, data); } - public static IdscpMessage createIdscpRatProverMessage(byte[] body){ + public static IdscpMessage createIdscpRatProverMessage(byte[] body) { IdscpRatProver idscpRatProver = IdscpRatProver.newBuilder() - .setData(ByteString.copyFrom(body)) - .build(); + .setData(ByteString.copyFrom(body)) + .build(); return IdscpMessage.newBuilder() .setIdscpRatProver(idscpRatProver) .build(); } - public static IdscpMessage createIdscpRatVerifierMessage(byte[] body){ + public static IdscpMessage createIdscpRatVerifierMessage(byte[] body) { IdscpRatVerifier idscpRatVerifier = IdscpRatVerifier.newBuilder() - .setData(ByteString.copyFrom(body)) - .build(); + .setData(ByteString.copyFrom(body)) + .build(); return IdscpMessage.newBuilder() .setIdscpRatVerifier(idscpRatVerifier) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index fbb1214c8..6c97a752f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -8,12 +8,12 @@ */ public class AttestationConfig { - public AttestationConfig(){ + public AttestationConfig() { } - public String[] getRatMechanisms(){ - return new String[] {"Dummy", "TPM2d"}; + public String[] getRatMechanisms() { + return new String[]{"Dummy", "TPM2d"}; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java index 64890880f..9ff5d8cf1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java @@ -3,11 +3,12 @@ import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +21,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Idscp2Configuration implements Idscp2Callback { +public class Idscp2Configuration implements SecureChannelInitListener { private static final Logger LOG = LoggerFactory.getLogger(Idscp2Configuration.class); private final Idscp2EndpointListener endpointListener; @@ -30,14 +31,13 @@ public class Idscp2Configuration implements Idscp2Callback { private final String[] localSupportedRatCipher; private final int ratTimeout; - public Idscp2Configuration(Idscp2EndpointListener endpointListener, DapsDriver dapsDriver, SecureChannelDriver secureChannelDriver, AttestationConfig expectedAttestation, AttestationConfig supportedAttestation, int ratTimeout - ){ + ) { this.endpointListener = endpointListener; this.dapsDriver = dapsDriver; this.secureChannelDriver = secureChannelDriver; @@ -46,11 +46,11 @@ public Idscp2Configuration(Idscp2EndpointListener endpointListener, this.ratTimeout = ratTimeout; } - /* + /** * User API to create a IDSCP2 connection as a client */ - public void connect(Idscp2Settings settings){ - LOG.info("Connect to an idscpv2 server ({})", settings.getHost()); + public void connect(Idscp2Settings settings) { + LOG.info("Connect to an IDSCP2 server ({})", settings.getHost()); secureChannelDriver.connect(settings, this); } @@ -61,85 +61,61 @@ public void connect(Idscp2Settings settings){ public Idscp2Server listen(Idscp2Settings settings) throws Idscp2Exception { LOG.info("Starting new IDSCP2 server at port {}", settings.getServerPort()); - // requires Promise - final var connectionPromise = new CompletableFuture(); - final SecureServer secureServer; - - if ((secureServer = secureChannelDriver.listen(settings, this, connectionPromise)) == null) { - throw new Idscp2Exception("Idscpv2 listen() failed. Cannot create SecureServer"); - } - - return new Idscp2Server(secureServer, connectionPromise); + final var serverListenerPromise = new CompletableFuture(); + final var secureServer = secureChannelDriver.listen(settings, this, serverListenerPromise); + final var server = new Idscp2Server(secureServer); + serverListenerPromise.complete(server); + return server; } - /* - * A callback implementation to receive a new established secure channel from an Secure client - * + /** + * A callback implementation to receive a new established secure channel from an Secure client/server. + *

* If the secure channel is null, no secure channel was established and an error is provided - * to the user - * + * to the user (or the error is ignored, in server case). + *

* If the secure channel was established, a new FSM is created for this connection and the * IDSCP2 handshake is started. After a successful handshake, a new Idscp2Connection is - * created and provided to the user + * created and provided to the user (and the IDSCP2 server). */ @Override - public void secureChannelConnectHandler(SecureChannel secureChannel) { - if (secureChannel == null){ - LOG.warn("IDSCP2 connect failed because no secure channel was established"); - endpointListener.onError("IDSCP2 connect failed because no secure channel was established"); + public synchronized void onSecureChannel(SecureChannel secureChannel, + CompletableFuture serverListenerPromise) { + if (secureChannel == null) { + LOG.warn("IDSCP2 connect failed because no secure channel available"); + endpointListener.onError("IDSCP2 connect failed because no secure channel available"); } else { - LOG.debug("A new secure channel for an outgoing idscpv2 connection was established"); + LOG.trace("A new secure channel for an IDSCP2 connection was established"); FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, - localExpectedRatCipher, ratTimeout); + localExpectedRatCipher, ratTimeout); try { - fsm.startIdscpHandshake(); //blocking until handshake is done - } catch (Idscp2Exception e){ + // Blocking until handshake is done + fsm.startIdscpHandshake(); + } catch (Idscp2Exception e) { return; } String connectionId = UUID.randomUUID().toString(); + // Threads calling onMessage() will be blocked until all listeners have been registered, see below Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); fsm.registerConnection(newConnection); - LOG.info("A new IDSCP2 connection with id {} was created", connectionId); - endpointListener.onConnection(newConnection); - } - } - - /* - * A callback implementation to receive a new established secure channel from an Secure server - * - * If the secure channel is null, no secure channel was established and the result will be - * ignored - * - * If the secure channel was established, a new FSM is created for this connection and the - * IDSCP2 handshake is started. After a successful handshake, a new Idscp2Connection is - * created and provided to the user and the IDSCP2 server - */ - @Override - public void secureChannelListenHandler(SecureChannel secureChannel, - CompletableFuture connectionPromise) { - if (secureChannel != null){ - LOG.debug("A new secure channel for an incoming idscpv2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, - localExpectedRatCipher, ratTimeout); - - try { - fsm.startIdscpHandshake(); //blocking until handshake is done - } catch (Idscp2Exception e){ - return; + LOG.debug("A new IDSCP2 connection with id {} was created", connectionId); + if (serverListenerPromise != null) { + // Complete the connection promise for the IDSCP server + serverListenerPromise.thenAccept(serverListener -> { + serverListener.onConnectionCreated(newConnection); + newConnection.addConnectionListener(new Idscp2ConnectionAdapter() { + @Override + public void onClose(Idscp2Connection connection) { + serverListener.onConnectionClose(connection); + } + }); + }); } - - //create new Idscp2Connection - String connectionId = UUID.randomUUID().toString(); - Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); - fsm.registerConnection(newConnection); - LOG.info("A new idscpv2 connection with id {} was created", connectionId); - // Complete the connection promise for the IDSCP server - connectionPromise.complete(newConnection); endpointListener.onConnection(newConnection); - } else { - LOG.warn("An incoming idscpv2 client connection request failed because the secure channel is null."); + newConnection.unlockMessaging(); } } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java index fc4021914..b2fa66ec9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java @@ -17,7 +17,7 @@ public class Idscp2Settings { private String trustStorePassword = "password"; private String keyStorePath = null; private String keyStorePassword = "password"; - private String certAlias = "1.0.1"; + private String certificateAlias = "1.0.1"; private String dapsKeyAlias = "1"; private String keyStoreKeyType = "RSA"; private AttestationConfig supportedAttestation = new AttestationConfig(); @@ -42,32 +42,32 @@ public Builder setServerPort(int serverPort) { } @NonNull - public Builder setTrustStore(String path) { + public Builder setTrustStorePath(String path) { this.settings.trustStorePath = path; return this; } @NonNull - public Builder setKeyStore(String path) { + public Builder setKeyStorePath(String path) { this.settings.keyStorePath = path; return this; } @NonNull - public Builder setTrustStorePwd(String pwd) { + public Builder setTrustStorePassword(String pwd) { this.settings.trustStorePassword = pwd; return this; } @NonNull - public Builder setKeyStorePwd(String pwd) { + public Builder setKeyStorePassword(String pwd) { this.settings.keyStorePassword = pwd; return this; } @NonNull public Builder setCertificateAlias(String alias) { - this.settings.certAlias = alias; + this.settings.certificateAlias = alias; return this; } @@ -84,13 +84,13 @@ public Builder setKeyStoreKeyType(String keyType) { } @NonNull - public Builder setSupportedAttestationSuite(AttestationConfig suite) { + public Builder setSupportedAttestation(AttestationConfig suite) { this.settings.supportedAttestation = suite; return this; } @NonNull - public Builder setExpectedAttestationSuite(AttestationConfig suite) { + public Builder setExpectedAttestation(AttestationConfig suite) { this.settings.expectedAttestation = suite; return this; } @@ -107,16 +107,20 @@ public Idscp2Settings build() { } - public AttestationConfig getExpectedAttestation() { - return expectedAttestation; + public int getServerPort() { + return serverPort; } - public AttestationConfig getSupportedAttestation() { - return supportedAttestation; + public String getHost() { + return host; } - public int getServerPort() { - return serverPort; + public String getTrustStorePath() { + return trustStorePath; + } + + public String getTrustStorePassword() { + return trustStorePassword; } public String getKeyStorePath() { @@ -127,31 +131,28 @@ public String getKeyStorePassword() { return keyStorePassword; } - public String getTrustStorePath() { - return trustStorePath; + public String getCertificateAlias() { + return certificateAlias; } - public String getTrustStorePassword() { - return trustStorePassword; + public String getDapsKeyAlias() { + return dapsKeyAlias; } public String getKeyStoreKeyType() { return keyStoreKeyType; } - public String getCertAlias() { - return certAlias; - } - - public String getDapsKeyAlias() { - return dapsKeyAlias; + public AttestationConfig getSupportedAttestation() { + return supportedAttestation; } - public String getHost() { - return host; + public AttestationConfig getExpectedAttestation() { + return expectedAttestation; } public int getRatTimeoutDelay() { return ratTimeoutDelay; } + } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java similarity index 52% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java index 9b7c4e948..2af24aa22 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Callback.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java @@ -1,6 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import java.util.concurrent.CompletableFuture; @@ -11,19 +11,14 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public interface Idscp2Callback { +public interface SecureChannelInitListener { - /* - * Notify the client about a new secure channel - */ - void secureChannelConnectHandler(SecureChannel secureChannel); - - /* + /** * Notify the server about new secureChannel */ - void secureChannelListenHandler( - SecureChannel secureChannel, - CompletableFuture connectionPromise + void onSecureChannel( + SecureChannel secureChannel, + CompletableFuture serverListenerPromise ); } \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java index 8f1b1a60f..15a1a804e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Event.java @@ -1,6 +1,6 @@ package de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine; -import de.fhg.aisec.ids.messages.IDSCP2.IdscpMessage; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2.IdscpMessage; /** * An Event class for the Finite State Machine. Triggers a transition and holds @@ -22,7 +22,7 @@ public enum EventType { /* * Create an Event with an Internal Control Message */ - public Event(InternalControlMessage controlMessage){ + public Event(InternalControlMessage controlMessage) { this.key = controlMessage.getValue(); this.type = EventType.INTERNAL_CONTROL_MESSAGE; this.controlMessage = controlMessage; @@ -32,7 +32,7 @@ public Event(InternalControlMessage controlMessage){ /* * Create an Event with an Idscpv2 Message */ - public Event (IdscpMessage idscpMessage){ + public Event(IdscpMessage idscpMessage) { this.key = idscpMessage.getMessageCase().getNumber(); this.type = EventType.IDSCP_MESSAGE; this.idscpMessage = idscpMessage; @@ -44,10 +44,9 @@ public Event (IdscpMessage idscpMessage){ * * throws an IllegalStateException if this event is requested for other purposes */ - public Event (InternalControlMessage controlMessage, IdscpMessage idscpMessage){ + public Event(InternalControlMessage controlMessage, IdscpMessage idscpMessage) { if (controlMessage.equals(InternalControlMessage.RAT_PROVER_MSG) || - controlMessage.equals(InternalControlMessage.RAT_VERIFIER_MSG)) - { + controlMessage.equals(InternalControlMessage.RAT_VERIFIER_MSG)) { this.key = controlMessage.getValue(); this.type = EventType.INTERNAL_CONTROL_MESSAGE; this.idscpMessage = idscpMessage; @@ -58,6 +57,16 @@ public Event (InternalControlMessage controlMessage, IdscpMessage idscpMessage){ } } + @Override + public String toString() { + return "Event{" + + "key=" + key + + ", type=" + type + + ", idscpMessage=" + idscpMessage + + ", controlMessage=" + controlMessage + + '}'; + } + // // Getter methods // diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 2960d7e9a..0b797578f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -5,23 +5,23 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.FastLatch; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; -import de.fhg.aisec.ids.messages.IDSCP2.IdscpMessage; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2.IdscpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * The finite state machine FSM of the IDSCP2 protocol - * + *

* Manages IDSCP2 Handshake, Re-Attestation, DAT-ReRequest and DAT-Re-Validation. Delivers * Internal Control Messages and Idscpv2Messages to the target receivers, * creates and manages the states and its transitions and implements security restriction to protect @@ -29,7 +29,7 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class FSM implements FsmListener{ +public class FSM implements FsmListener { private static final Logger LOG = LoggerFactory.getLogger(FSM.class); /* ----------- IDSCP2 Protocol States ---------- */ @@ -75,7 +75,7 @@ enum FSM_STATE { * lost */ private Idscp2Connection connection; - private final CountDownLatch connectionLatch = new CountDownLatch(1); + private final FastLatch connectionLatch = new FastLatch(); /* * A FIFO-fair synchronization lock for the finite state machine @@ -109,7 +109,7 @@ enum FSM_STATE { /* ---------------- end of Timer --------------- */ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, - String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout){ + String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout) { /* ------------- Timeout Handler Routines ------------*/ @@ -154,22 +154,22 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, )); states.put(FSM_STATE.STATE_WAIT_FOR_RAT, new StateWaitForRat(this, handshakeTimer, - verifierHandshakeTimer, proverHandshakeTimer, ratTimer, ratTimeout, dapsDriver)); + verifierHandshakeTimer, proverHandshakeTimer, ratTimer, ratTimeout, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_RAT_PROVER, new StateWaitForRatProver(this, - ratTimer, handshakeTimer, proverHandshakeTimer, dapsDriver)); + ratTimer, handshakeTimer, proverHandshakeTimer, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER, new StateWaitForRatVerifier(this, - dapsDriver, ratTimer, handshakeTimer, verifierHandshakeTimer, ratTimeout)); + dapsDriver, ratTimer, handshakeTimer, verifierHandshakeTimer, ratTimeout)); states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT, new StateWaitForDatAndRat(this, - handshakeTimer, proverHandshakeTimer, datTimer, dapsDriver)); + handshakeTimer, proverHandshakeTimer, datTimer, dapsDriver)); states.put(FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER, - new StateWaitForDatAndRatVerifier(this, handshakeTimer, datTimer, dapsDriver)); + new StateWaitForDatAndRatVerifier(this, handshakeTimer, datTimer, dapsDriver)); states.put(FSM_STATE.STATE_ESTABLISHED, new StateEstablished(this, dapsDriver, - ratTimer, handshakeTimer)); + ratTimer, handshakeTimer)); //set initial state @@ -181,14 +181,13 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, } private void checkForFsmCircles() { - // check if current thread holds already the fsm lock, then we have a circle // this runs into an issue: onControlMessage must be called only from other threads! // if the current thread currently stuck within a fsm transition it will trigger another // transition on the old state and undefined behaviour occurred // - // The idscpv2 core and default driver will not run into this issue. It's a protection for - // avoiding incorrect usage of the idscpv2 library from further driver implementations + // The IDSCP2 core and default driver will not run into this issue. It's a protection for + // avoiding incorrect usage of the IDSCP2 library from further driver implementations // // Example: // Thread A stuck within a transition t1 that calls a function that calls @@ -201,8 +200,11 @@ private void checkForFsmCircles() { // vulnerabilities // if (fsmIsBusy.isHeldByCurrentThread()) { - throw new RuntimeException("The current thread holds the fsm lock already. " - + "A circle might occur that could lead to undefined behaviour within the fsm"); + final var e = new RuntimeException("The current thread holds the fsm lock already. " + + "A circle might occur that could lead to undefined behaviour within the fsm"); + // Log exception before throwing, since some threads swallow the exception without any notification + LOG.error(e.getMessage(), e); + throw e; } } @@ -213,7 +215,7 @@ private void checkForFsmCircles() { * driver implementations */ @Override - public void onMessage(byte[] data){ + public void onMessage(byte[] data) { //check for incorrect usage checkForFsmCircles(); @@ -233,7 +235,7 @@ public void onMessage(byte[] data){ // leaving STATE_CLOSED fsmIsBusy.lock(); try { - while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))){ + while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { if (fsmIsClosed) { return; @@ -285,7 +287,7 @@ public void onRatProverMessage(InternalControlMessage controlMessage, byte[] rat //only allow rat prover messages from current thread Event e; - if (ratMessage == null){ + if (ratMessage == null) { e = new Event(controlMessage); } else { IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpRatProverMessage(ratMessage); @@ -323,7 +325,7 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] r //only allow rat verifier messages from current thread Event e; - if (ratMessage == null){ + if (ratMessage == null) { e = new Event(controlMessage); } else { IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpRatVerifierMessage(ratMessage); @@ -331,7 +333,7 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] r } fsmIsBusy.lock(); - try{ + try { if (Long.toString(Thread.currentThread().getId()).equals(currentRatVerifierId)) { feedEvent(e); } else { @@ -345,7 +347,7 @@ public void onRatVerifierMessage(InternalControlMessage controlMessage, byte[] r /* * Feed the event to the current state and execute the runEntry method if the state has changed */ - private void feedEvent(Event event){ + private void feedEvent(Event event) { State prevState = currentState; currentState = currentState.feedEvent(event); @@ -360,15 +362,15 @@ private void feedEvent(Event event){ * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect * driver implementations */ - public void terminate(){ - + public void terminate() { //check for incorrect usage checkForFsmCircles(); - LOG.info("Close idscp connection"); + LOG.debug("Close IDSCP2 connection"); onControlMessage(InternalControlMessage.IDSCP_STOP); - LOG.debug("Close secure channel"); + LOG.trace("Close secure channel"); secureChannel.close(); + LOG.debug("IDSCP2 connection closed"); } /* @@ -397,7 +399,7 @@ public void startIdscpHandshake() throws Idscp2Exception { idscpHandshakeLock.await(); } - if (!isConnected()){ + if (!isConnected()) { //handshake failed, throw exception throw new Idscp2Exception("Handshake failed"); } @@ -415,7 +417,7 @@ public void startIdscpHandshake() throws Idscp2Exception { /* * Send idscp data from the fsm via the secure channel to the peer */ - boolean sendFromFSM(IdscpMessage msg){ + boolean sendFromFSM(IdscpMessage msg) { //send messages from fsm return secureChannel.send(msg.toByteArray()); } @@ -427,7 +429,7 @@ boolean sendFromFSM(IdscpMessage msg){ * driver implementations */ @Override - public void onError(){ + public void onError() { //check for incorrect usage checkForFsmCircles(); @@ -442,7 +444,7 @@ public void onError(){ * driver implementations */ @Override - public void onClose(){ + public void onClose() { //check for incorrect usage checkForFsmCircles(); @@ -453,11 +455,11 @@ public void onClose(){ /* * Send idscp message from the User via the secure channel */ - public void send(String type, byte[] msg){ + public void send(String type, byte[] msg) { //send messages from user only when idscp connection is established fsmIsBusy.lock(); - try{ - if(isConnected()){ + try { + if (isConnected()) { IdscpMessage idscpMessage = Idscp2MessageHelper.createIdscpDataMessage(type, msg); if (!secureChannel.send(idscpMessage.toByteArray())) { LOG.error("Cannot send IDSCP_DATA via secure channel"); @@ -474,22 +476,22 @@ public void send(String type, byte[] msg){ /* * Check if FSM is in STATE ESTABLISHED */ - public boolean isConnected(){ + public boolean isConnected() { return currentState.equals(states.get(FSM_STATE.STATE_ESTABLISHED)); } /* * Register an IDSCP2 message listener */ - public void registerConnection(Idscp2Connection connection){ + public void registerConnection(Idscp2Connection connection) { this.connection = connection; - connectionLatch.countDown(); + connectionLatch.unlock(); } /* * Notify handshake lock about result */ - void notifyHandshakeCompleteLock(){ + void notifyHandshakeCompleteLock() { fsmIsBusy.lock(); try { handshakeResultAvailable = true; @@ -504,7 +506,7 @@ void notifyHandshakeCompleteLock(){ * * Return the String of the cipher or null if no match was found */ - String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier){ + String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpectedVerifier) { //toDo implement logic return localSupportedProver[0]; } @@ -514,7 +516,7 @@ String getRatProverMechanism(String[] localSupportedProver, Object[] remoteExpec * * Return the String of the cipher or null if no match was found */ - String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver){ + String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSupportedProver) { //toDo implement logic return localExpectedVerifier[0]; } @@ -526,11 +528,11 @@ String getRatVerifierMechanism(String[] localExpectedVerifier, Object[] remoteSu * return false if no match was found */ @SuppressWarnings("BooleanMethodIsAlwaysInverted") - boolean restartRatVerifierDriver(){ + boolean restartRatVerifierDriver() { //assume verifier mechanism is set stopRatVerifierDriver(); ratVerifierDriver = RatVerifierDriverRegistry.startRatVerifierDriver(verifierMechanism, this); - if (ratVerifierDriver == null){ + if (ratVerifierDriver == null) { LOG.error("Cannot create instance of RAT_VERIFIER_DRIVER"); currentRatVerifierId = ""; return false; @@ -548,7 +550,7 @@ boolean restartRatVerifierDriver(){ */ void stopRatVerifierDriver() { verifierHandshakeTimer.cancelTimeout(); - if (ratVerifierDriver != null && ratVerifierDriver.isAlive()){ + if (ratVerifierDriver != null && ratVerifierDriver.isAlive()) { ratVerifierDriver.interrupt(); ratVerifierDriver.terminate(); } @@ -561,11 +563,11 @@ void stopRatVerifierDriver() { * return false if no match was found */ @SuppressWarnings("BooleanMethodIsAlwaysInverted") - boolean restartRatProverDriver(){ + boolean restartRatProverDriver() { //assume prover mechanism is set stopRatProverDriver(); ratProverDriver = RatProverDriverRegistry.startRatProverDriver(proverMechanism, this); - if (ratProverDriver == null){ + if (ratProverDriver == null) { LOG.error("Cannot create instance of RAT_PROVER_DRIVER"); currentRatProverId = ""; return false; @@ -581,9 +583,9 @@ boolean restartRatProverDriver(){ /* * Terminate the RatProverDriver */ - void stopRatProverDriver(){ + void stopRatProverDriver() { proverHandshakeTimer.cancelTimeout(); - if (ratProverDriver != null && ratProverDriver.isAlive()){ + if (ratProverDriver != null && ratProverDriver.isAlive()) { ratProverDriver.interrupt(); ratProverDriver.terminate(); } @@ -604,16 +606,12 @@ void shutdownFsm() { this.stopRatVerifierDriver(); fsmIsClosed = true; - //notify upper layer via handshake or closeListener - try { - if (handshakeResultAvailable) { - connectionLatch.await(); - connection.onClose(); - } else { - notifyHandshakeCompleteLock(); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + // Notify upper layer via handshake or closeListener + if (handshakeResultAvailable) { + connectionLatch.await(); + connection.onClose(); + } else { + notifyHandshakeCompleteLock(); } } @@ -621,13 +619,9 @@ void shutdownFsm() { * Provide IDSCP2 message to the message listener */ void notifyIdscpMsgListener(String type, byte[] data) { - try { - this.connectionLatch.await(); - this.connection.onMessage(type, data); - LOG.debug("Idscp data were passed to connection listener"); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } + this.connectionLatch.await(); + this.connection.onMessage(type, data); + LOG.debug("Idscp data has been passed to connection listener"); } // @@ -642,10 +636,14 @@ RatProverDriver getRatProverDriver() { return ratProverDriver; } - State getState(FSM_STATE state){ + State getState(FSM_STATE state) { return states.get(state); } + public boolean isNotClosed() { + return currentState.equals(getState(FSM_STATE.STATE_CLOSED)); + } + // // Setter // diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java index d569e8ba9..671ed27e0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/InternalControlMessage.java @@ -2,7 +2,7 @@ /** * An enum that wraps the internal control messages of the IDSCP2 protocol to trigger transitions - * by non-idscpv2-message-events + * by non-IDSCP2-message-events * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ @@ -23,6 +23,12 @@ public enum InternalControlMessage { //set unique values that are different from IdscpMessage.MessageCase ot identify event.key private final String id; - InternalControlMessage(String id) {this.id = id;} - public String getValue() {return id;} + + InternalControlMessage(String id) { + this.id = id; + } + + public String getValue() { + return id; + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java index 412b84c59..0d301e5e8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/State.java @@ -12,8 +12,8 @@ */ public class State { - private final ConcurrentHashMap transitions = new ConcurrentHashMap<>(); - private Function noTransitionHandler = null; + private final ConcurrentHashMap transitions = new ConcurrentHashMap<>(); + private Function noTransitionHandler = null; /* * A method for triggering aa transition of the current state by a given event @@ -22,9 +22,9 @@ public class State { * * Returns the target state of the triggered transition (new current state of the fsm) */ - State feedEvent(Event e){ + State feedEvent(Event e) { Transition t = transitions.get(e.getKey()); - if (t != null){ + if (t != null) { return t.doTransition(e); } else { return noTransitionHandler.apply(e); @@ -34,8 +34,8 @@ State feedEvent(Event e){ /* * Add ann outgoing transition to the state */ - void addTransition(Object k, Transition t){ - transitions.put(k,t); + void addTransition(Object k, Transition t) { + transitions.put(k, t); } /* @@ -48,6 +48,7 @@ void setNoTransitionHandler(Function noTransitionHandler) { /* * run a sequence of code when the state is entered */ - void runEntryCode(FSM fsm) {} + void runEntryCode(FSM fsm) { + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index 8b5c0f5fb..b6acac5b5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -4,18 +4,20 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; import java.util.concurrent.locks.Condition; +import java.util.stream.Collectors; /** * The Closed State of the FSM of the IDSCP2 protocol. * The FSM is in the Closed state either before any transition was triggered (in this case, the * Closed State is the FSM Start state) or after the connection was closed (in this case, the * Closed State is the FSM final state without any outgoing transitions) - * + *

* When the FSM go from any State into the Closed State again, the FSM is locked forever and all * involved actors like RatDrivers and Timers will be terminated * @@ -28,7 +30,7 @@ public StateClosed(FSM fsm, DapsDriver dapsDriver, Condition onMessageLock, String[] localSupportedRatSuite, - String[] localExpectedRatSuite){ + String[] localExpectedRatSuite) { /*--------------------------------------------------- @@ -45,13 +47,13 @@ public StateClosed(FSM fsm, LOG.debug("Send IDSCP_HELLO"); IDSCP2.IdscpMessage idscpHello = Idscp2MessageHelper. - createIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); + createIdscpHelloMessage(dat, localSupportedRatSuite, localExpectedRatSuite); if (!fsm.sendFromFSM(idscpHello)) { - LOG.error("Cannot send IdscpHello. Close connection"); - runEntryCode(fsm); - onMessageLock.signalAll(); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send IdscpHello. Close connection"); + runEntryCode(fsm); + onMessageLock.signalAll(); + return fsm.getState(FSM_STATE.STATE_CLOSED); } runExitCode(onMessageLock); @@ -62,7 +64,12 @@ public StateClosed(FSM fsm, this.setNoTransitionHandler( event -> { - LOG.debug("No transition available for given event " + event.toString()); + LOG.debug("No transition available for given event {}, stack trace for analysis:\n{}", + event, + Arrays.stream(Thread.currentThread().getStackTrace()) + .skip(1) + .map(Object::toString) + .collect(Collectors.joining("\n"))); LOG.debug("Stay in state STATE_CLOSED"); return this; } @@ -70,13 +77,13 @@ public StateClosed(FSM fsm, } - private void runExitCode(Condition onMessageLock){ + private void runExitCode(Condition onMessageLock) { //State Closed exit code onMessageLock.signalAll(); //enables fsm.onMessage() } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { //State Closed entry code LOG.debug("Switched to state STATE_CLOSED"); LOG.debug("Terminate and free all resources and lock fsm forever"); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java index 4e9a865bc..b7e09f9a9 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateEstablished.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,13 +58,13 @@ public StateEstablished(FSM fsm, ratTimer.cancelTimeout(); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpReRatMessage(""))) { - LOG.error("Cannot send ReRat message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send ReRat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatVerifierDriver()) { - LOG.error("Cannot run Rat verifier, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); @@ -76,14 +76,14 @@ public StateEstablished(FSM fsm, ratTimer.cancelTimeout(); LOG.debug("Remote DAT expired. Send IDSCP_DAT_EXPIRED"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { - LOG.error("Cannot send DatExpired message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } - LOG.debug("Set handshake timeout"); - handshakeTimer.resetTimeout(5); + LOG.debug("Set handshake timeout"); + handshakeTimer.resetTimeout(5); - return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); + return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER); } )); @@ -92,8 +92,8 @@ public StateEstablished(FSM fsm, LOG.debug("Received IDSCP_RERAT. Start RAT_PROVER"); if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); @@ -105,13 +105,13 @@ public StateEstablished(FSM fsm, LOG.debug("DAT expired. Send new DAT and repeat RAT"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send Dat message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send Dat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_PROVER); @@ -143,7 +143,7 @@ public StateEstablished(FSM fsm, } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { LOG.debug("Switched to state STATE_ESTABLISHED"); fsm.notifyHandshakeCompleteLock(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java index 8d4b688c4..afd823d77 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRat.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +22,7 @@ public StateWaitForDatAndRat(FSM fsm, Timer proverHandshakeTimer, Timer datTimer, DapsDriver dapsDriver - ){ + ) { /*--------------------------------------------------- * STATE_WAIT_FOR_DAT_AND_RAT - Transition Description @@ -44,7 +44,7 @@ public StateWaitForDatAndRat(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { LOG.debug("Send IDSC_CLOSE"); - fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -88,8 +88,8 @@ public StateWaitForDatAndRat(FSM fsm, event -> { LOG.debug("Send IDSCP_RAT_PROVER"); if (!fsm.sendFromFSM(event.getIdscpMessage())) { - LOG.error("Cannot send rat prover message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; } @@ -109,10 +109,10 @@ public StateWaitForDatAndRat(FSM fsm, //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); long datValidityPeriod; - if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))) { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage( - "No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); + "No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -120,8 +120,8 @@ public StateWaitForDatAndRat(FSM fsm, datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier if (!fsm.restartRatVerifierDriver()) { - LOG.error("Cannot run Rat verifier, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); @@ -133,13 +133,13 @@ public StateWaitForDatAndRat(FSM fsm, LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send Dat message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send Dat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -151,7 +151,7 @@ public StateWaitForDatAndRat(FSM fsm, LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() - .getData().toByteArray()); + .getData().toByteArray()); return this; } )); @@ -160,8 +160,8 @@ public StateWaitForDatAndRat(FSM fsm, event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; } @@ -176,7 +176,7 @@ public StateWaitForDatAndRat(FSM fsm, } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java index 80ae6af9a..afaa67b9b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForDatAndRatVerifier.java @@ -3,14 +3,14 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The Wait_For_Dat_And_Rat_Verifier State of the FSM of the IDSCP2 protocol. * Wait for a new dynamic attribute token from the peer, since the old one is not valid anymore - * and waits for the RatVerifier after successful verification of the Dat to decide if the idscpv2 + * and waits for the RatVerifier after successful verification of the Dat to decide if the IDSCP2 * connection will be established * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -21,7 +21,7 @@ public class StateWaitForDatAndRatVerifier extends State { public StateWaitForDatAndRatVerifier(FSM fsm, Timer handshakeTimer, Timer datTimer, - DapsDriver dapsDriver){ + DapsDriver dapsDriver) { /*--------------------------------------------------- * STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER - Transition Description @@ -75,7 +75,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, //check if Dat is available and verify dat byte[] dat = event.getIdscpMessage().getIdscpDat().getToken().toByteArray(); long datValidityPeriod; - if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))){ + if (0 > (datValidityPeriod = dapsDriver.verifyToken(dat, null))) { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); @@ -84,8 +84,8 @@ public StateWaitForDatAndRatVerifier(FSM fsm, datTimer.resetTimeout(datValidityPeriod); //start RAT Verifier if (!fsm.restartRatVerifierDriver()) { - LOG.error("Cannot run Rat verifier, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT_VERIFIER); @@ -97,13 +97,13 @@ public StateWaitForDatAndRatVerifier(FSM fsm, LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send DAT message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } @@ -113,8 +113,8 @@ public StateWaitForDatAndRatVerifier(FSM fsm, event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_DAT_AND_RAT); } @@ -129,7 +129,7 @@ public StateWaitForDatAndRatVerifier(FSM fsm, } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { LOG.debug("Switched to state STATE_WAIT_FOR_DAT_AND_RAT_VERIFIER"); LOG.debug("Set handshake timeout"); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index cbfec036e..db821241b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,7 +11,7 @@ * The Wait_For_Hello State of the FSM of the IDSCP2 protocol. * Waits for the Idscpv2 Hellp Message that contains the protocol version, the supported and * expected remote attestation cipher suites and the dynamic attribute token (DAT) of the peer. - * + *

* Goes into the WAIT_FOR_RAT State when valid Rat mechanisms were found and the DAT is valid * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) @@ -85,18 +85,20 @@ public StateWaitForHello(FSM fsm, LOG.debug("Calculate Rat mechanisms"); String proverMechanism = fsm.getRatProverMechanism(localSupportedRatSuite, idscpHello.getExpectedRatSuiteList().toArray()); - if (proverMechanism == null){ + if (proverMechanism == null) { LOG.debug("Cannot find a match for RAT proverr. Send IDSCP_CLOSE"); - fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No match for RAT Prover mechanism", + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage( + "No match for RAT Prover mechanism", IDSCP2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_PROVER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } String verifierMechanism = fsm.getRatVerifierMechanism(localExpectedRatSuite, idscpHello.getSupportedRatSuiteList().toArray()); - if (verifierMechanism == null){ + if (verifierMechanism == null) { LOG.debug("Cannot find a match for RAT verifier. Send IDSCP_CLOSE"); - fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No match for RAT Verifier mechanism", + fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage( + "No match for RAT Verifier mechanism", IDSCP2.IdscpClose.CloseCause.NO_RAT_MECHANISM_MATCH_VERIFIER)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -105,7 +107,7 @@ public StateWaitForHello(FSM fsm, //check if Dat is available and verify dat long datValidityPeriod; if (!idscpHello.hasDynamicAttributeToken() || 0 > (datValidityPeriod = dapsDriver - .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))){ + .verifyToken(idscpHello.getDynamicAttributeToken().getToken().toByteArray(), null))) { LOG.debug("No valid remote DAT is available. Send IDSCP_CLOSE"); fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("No valid DAT", IDSCP2.IdscpClose.CloseCause.NO_VALID_DAT)); @@ -120,13 +122,13 @@ public StateWaitForHello(FSM fsm, LOG.debug("Start RAT Prover and Verifier"); if (!fsm.restartRatVerifierDriver()) { - LOG.error("Cannot run Rat verifier, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index ff05c3c1d..5aa079906 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +23,7 @@ public StateWaitForRat(FSM fsm, Timer proverHandshakeTimer, Timer ratTimer, int ratTimerDelay, - DapsDriver dapsDriver){ + DapsDriver dapsDriver) { /*--------------------------------------------------- @@ -46,7 +46,7 @@ public StateWaitForRat(FSM fsm, * ALL_OTHER_MESSAGES ---> {} ---> STATE_WAIT_FOR_RAT * --------------------------------------------------- */ this.addTransition(InternalControlMessage.ERROR.getValue(), new Transition( - event -> { + event -> { LOG.debug("An internal control error occurred"); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); } @@ -103,8 +103,8 @@ public StateWaitForRat(FSM fsm, LOG.debug("Send IDSCP_RAT_PROVER"); if (!fsm.sendFromFSM(event.getIdscpMessage())) { - LOG.error("Cannot send rat prover message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -116,8 +116,8 @@ public StateWaitForRat(FSM fsm, LOG.debug("Send IDSCP_RAT_VERIFIER"); if (!fsm.sendFromFSM(event.getIdscpMessage())) { - LOG.error("Cannot send rat verifier message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send rat verifier message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -130,8 +130,8 @@ public StateWaitForRat(FSM fsm, fsm.stopRatVerifierDriver(); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { - LOG.error("Cannot send DatExpired message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } LOG.debug("Start Handshake Timer"); @@ -155,7 +155,7 @@ public StateWaitForRat(FSM fsm, LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() - .getData().toByteArray()); + .getData().toByteArray()); return this; } @@ -166,7 +166,7 @@ public StateWaitForRat(FSM fsm, LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); assert event.getIdscpMessage().hasIdscpRatProver(); fsm.getRatVerifierDriver().delegate(event.getIdscpMessage().getIdscpRatProver() - .getData().toByteArray()); + .getData().toByteArray()); return this; } @@ -177,13 +177,13 @@ public StateWaitForRat(FSM fsm, LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send DAT message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -206,8 +206,8 @@ public StateWaitForRat(FSM fsm, ); } - @Override - void runEntryCode(FSM fsm){ + @Override + void runEntryCode(FSM fsm) { LOG.debug("Switch to state STATE_WAIT_FOR_RAT"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java index 9978c65ee..dc5f144d5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatProver.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +20,7 @@ public StateWaitForRatProver(FSM fsm, Timer ratTimer, Timer handshakeTimer, Timer proverHandshakeTimer, - DapsDriver dapsDriver){ + DapsDriver dapsDriver) { /*--------------------------------------------------- @@ -70,8 +70,8 @@ public StateWaitForRatProver(FSM fsm, ratTimer.cancelTimeout(); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { - LOG.error("Cannot send DatExpired message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } LOG.debug("Start Handshake Timer"); @@ -104,8 +104,8 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("Send IDSCP_RAT_PROVER"); if (!fsm.sendFromFSM(event.getIdscpMessage())) { - LOG.error("Cannot send rat prover message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send rat prover message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -117,15 +117,15 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("Request RAT repeat. Send IDSCP_RE_RAT, start RAT_VERIFIER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpReRatMessage(""))) { - LOG.error("Cannot send ReRat message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send ReRat message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } ratTimer.cancelTimeout(); if (!fsm.restartRatVerifierDriver()) { - LOG.error("Cannot run Rat verifier, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat verifier, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); @@ -144,13 +144,13 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, restart RAT_PROVER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send DAT message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -162,7 +162,7 @@ public StateWaitForRatProver(FSM fsm, LOG.debug("Delegate received IDSCP_RAT_VERIFIER to RAT_PROVER"); assert event.getIdscpMessage().hasIdscpRatVerifier(); fsm.getRatProverDriver().delegate(event.getIdscpMessage().getIdscpRatVerifier() - .getData().toByteArray()); + .getData().toByteArray()); return this; } @@ -172,8 +172,8 @@ public StateWaitForRatProver(FSM fsm, event -> { LOG.debug("Received IDSCP_RE_RAT. Restart RAT_PROVER"); if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; } @@ -189,7 +189,7 @@ public StateWaitForRatProver(FSM fsm, } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { LOG.debug("Switched to state STATE_WAIT_FOR_RAT_PROVER"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 77b74f9ea..211082e3d 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -3,7 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM.FSM_STATE; -import de.fhg.aisec.ids.messages.IDSCP2; +import de.fhg.aisec.ids.idscp2.messages.IDSCP2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,8 +69,8 @@ public StateWaitForRatVerifier(FSM fsm, fsm.stopRatVerifierDriver(); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatExpiredMessage())) { - LOG.error("Cannot send DatExpired message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DatExpired message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } LOG.debug("Start Handshake Timer"); @@ -105,8 +105,8 @@ public StateWaitForRatVerifier(FSM fsm, LOG.debug("Send IDSCP_RAT_VERIFIER"); if (!fsm.sendFromFSM(event.getIdscpMessage())) { - LOG.error("Cannot send rat verifier message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send rat verifier message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return this; @@ -125,13 +125,13 @@ public StateWaitForRatVerifier(FSM fsm, LOG.debug("Received IDSCP_DAT_EXPIRED. Send new DAT from DAT_DRIVER, start RAT_PROVER"); if (!fsm.sendFromFSM(Idscp2MessageHelper.createIdscpDatMessage(dapsDriver.getToken()))) { - LOG.error("Cannot send DAT message"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot send DAT message"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); @@ -143,7 +143,7 @@ public StateWaitForRatVerifier(FSM fsm, LOG.debug("Delegate received IDSCP_RAT_PROVER to RAT_VERIFIER"); assert event.getIdscpMessage().hasIdscpRatProver(); fsm.getRatVerifierDriver().delegate(event.getIdscpMessage().getIdscpRatProver() - .getData().toByteArray()); + .getData().toByteArray()); return this; } )); @@ -152,8 +152,8 @@ public StateWaitForRatVerifier(FSM fsm, event -> { LOG.debug("Received IDSCP_RE_RAT. Start RAT_PROVER"); if (!fsm.restartRatProverDriver()) { - LOG.error("Cannot run Rat prover, close idscp connection"); - return fsm.getState(FSM_STATE.STATE_CLOSED); + LOG.error("Cannot run Rat prover, close idscp connection"); + return fsm.getState(FSM_STATE.STATE_CLOSED); } return fsm.getState(FSM.FSM_STATE.STATE_WAIT_FOR_RAT); } @@ -169,7 +169,7 @@ public StateWaitForRatVerifier(FSM fsm, } @Override - void runEntryCode(FSM fsm){ + void runEntryCode(FSM fsm) { LOG.debug("Switched to state STATE_WAIT_FOR_RAT_VERIFIER"); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java index b2b2643ab..44a78b5ad 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Timer.java @@ -15,12 +15,12 @@ public class Timer { private final ReentrantLock mutex = new ReentrantLock(true); private final Runnable timeoutHandler; - Timer(ReentrantLock fsmIsBusy, Runnable timeoutHandler){ + Timer(ReentrantLock fsmIsBusy, Runnable timeoutHandler) { this.fsmIsBusy = fsmIsBusy; this.timeoutHandler = timeoutHandler; } - void resetTimeout(long delay){ + void resetTimeout(long delay) { cancelTimeout(); start(delay); } @@ -28,7 +28,7 @@ void resetTimeout(long delay){ /* * Start a timer thread that triggers the timeout handler routine after a given timout delay */ - public void start(long delay){ + public void start(long delay) { mutex.lock(); thread = new TimerThread(delay, timeoutHandler, fsmIsBusy); thread.start(); @@ -38,9 +38,9 @@ public void start(long delay){ /* * Cancel the current timer thread */ - void cancelTimeout(){ + void cancelTimeout() { mutex.lock(); - if (thread != null){ + if (thread != null) { thread.safeStop(); thread = null; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java index dd01ca635..c6cd4ccfa 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/TimerThread.java @@ -9,14 +9,14 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class TimerThread extends Thread{ +public class TimerThread extends Thread { private volatile boolean canceled = false; private final long delay; //timeout delay in seconds private final Runnable timeoutHandler; //timeout handler routine private final ReentrantLock fsmIsBusy; //lock for the fsm - TimerThread(long delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy){ + TimerThread(long delay, Runnable timeoutHandler, ReentrantLock fsmIsBusy) { this.delay = delay; this.timeoutHandler = timeoutHandler; this.fsmIsBusy = fsmIsBusy; @@ -31,7 +31,7 @@ public class TimerThread extends Thread{ * If the timout was not canceled so far, the timer thread calls a timeout handler * routine, that triggers the timeout transition in the fsm */ - public void run(){ + public void run() { try { Thread.sleep(delay * 1000); } catch (InterruptedException e) { @@ -46,7 +46,7 @@ public void run(){ fsmIsBusy.lock(); try { - if (!canceled){ + if (!canceled) { timeoutHandler.run(); } } finally { @@ -57,7 +57,7 @@ public void run(){ /* * A method to stop the execution of the timer thread and cancel the timeout */ - public void safeStop(){ + public void safeStop() { canceled = true; this.interrupt(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java index 3ab864f57..95ed0ba81 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/Transition.java @@ -9,13 +9,13 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ class Transition { - private final Function eventHandler; + private final Function eventHandler; - Transition(Function eventHandler){ + Transition(Function eventHandler) { this.eventHandler = eventHandler; } - State doTransition(Event e){ + State doTransition(Event e) { return eventHandler.apply(e); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java index 80bc672ac..5f54eae88 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/Idscp2Server.java @@ -5,10 +5,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collection; import java.util.Collections; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; +import java.util.HashSet; +import java.util.Set; /** * An IDSCP2 Server that has the control about the underlying secure server and caches all active @@ -16,58 +15,56 @@ * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Idscp2Server { +public class Idscp2Server implements ServerConnectionListener { private static final Logger LOG = LoggerFactory.getLogger(Idscp2Server.class); private final SecureServer secureServer; - private final ConcurrentHashMap connections = new ConcurrentHashMap<>(); + private final Set connections = Collections.synchronizedSet(new HashSet<>()); - public Idscp2Server(SecureServer secureServer, CompletableFuture connectionPromise) { + public Idscp2Server(SecureServer secureServer) { this.secureServer = secureServer; - connectionPromise.thenAccept(connection -> connections.put(connection.getConnectionId(), connection)); } /* * Terminate the IDSCP2 server, the secure server and close all connections */ - public void terminate(){ - LOG.info("Terminating idscp server {}", this.toString()); - secureServer.safeStop(); + public void terminate() { + LOG.info("Terminating IDSCP2 server {}", this.toString()); terminateAllSessions(); + secureServer.safeStop(); } /* * Close all open IDSCP2 connections of this server */ - public void terminateAllSessions(){ - for (Idscp2Connection c : connections.values()){ - c.close(); - LOG.debug("Idscp connection with id {} has been closed", c.getConnectionId()); - connections.remove(c.getConnectionId()); + public void terminateAllSessions() { + for (Idscp2Connection connection : connections) { + connection.close(); + LOG.debug("Idscp connection with id {} has been closed", connection.getId()); + connections.remove(connection); } } - /* - * Check if the server is running - */ - public boolean isRunning(){ - return secureServer.isRunning(); + public void onConnectionCreated(Idscp2Connection connection) { + connections.add(connection); + } + + public void onConnectionClose(Idscp2Connection connection) { + connections.remove(connection); } /* - * Get a Idscp2Connection from the server cache by the connectionID - * - * return null if no connection was found with this ID + * Check if the server is running */ - public Idscp2Connection getConnectionById(String connectionId){ - return connections.get(connectionId); + public boolean isRunning() { + return secureServer.isRunning(); } /* * return a list of all open IDSCP2 connections of this server */ - public Collection getAllConnections(){ - return Collections.unmodifiableCollection(connections.values()); + public Set getAllConnections() { + return Collections.unmodifiableSet(connections); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/ServerConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/ServerConnectionListener.java new file mode 100644 index 000000000..548a7f051 --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/idscp_server/ServerConnectionListener.java @@ -0,0 +1,10 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.idscp_server; + +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; + +public interface ServerConnectionListener { + + void onConnectionCreated(Idscp2Connection connection); + + void onConnectionClose(Idscp2Connection connection); +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java index 552307aca..a9c052dfa 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatProverDriverRegistry.java @@ -9,7 +9,7 @@ /** * A Rat Prover Driver Registry * The User can register Driver implementation instances and its configurations to the registry - * + *

* The Idscpv2 protocol will select during the idscp handshake a Rat Prover mechanism and will * check for this RatProver in this registry * @@ -19,11 +19,12 @@ public class RatProverDriverRegistry { private static RatProverDriverRegistry instance; private static final ConcurrentHashMap drivers = new ConcurrentHashMap<>(); - private RatProverDriverRegistry(){} + private RatProverDriverRegistry() { + } - public static RatProverDriverRegistry getInstance(){ - if (instance == null){ - instance = new RatProverDriverRegistry(); + public static RatProverDriverRegistry getInstance() { + if (instance == null) { + instance = new RatProverDriverRegistry(); } return instance; @@ -38,7 +39,7 @@ public static RatProverDriverRegistry getInstance(){ * The finite state machine is registered as the communication partner for the RatProver. * The RatProver will be initialized with a configuration, if present. Then it is started. */ - public static RatProverDriver startRatProverDriver(String instance, FsmListener listener){ + public static RatProverDriver startRatProverDriver(String instance, FsmListener listener) { DriverWrapper driverWrapper = drivers.get(instance); if (driverWrapper == null) { return null; @@ -54,7 +55,7 @@ public static RatProverDriver startRatProverDriver(String instance, FsmListener return driver; } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | - InvocationTargetException e) { + InvocationTargetException e) { return null; } } @@ -64,17 +65,17 @@ public static RatProverDriver startRatProverDriver(String instance, FsmListener * Register Rat Prover driver and an optional configuration in the registry */ public void registerDriver( - String instance, - Class driverClass, - Object driverConfig - ){ + String instance, + Class driverClass, + Object driverConfig + ) { drivers.put(instance, new DriverWrapper(driverClass, driverConfig)); } /* * Unregister the driver from the registry */ - public void unregisterDriver(String instance){ + public void unregisterDriver(String instance) { drivers.remove(instance); } @@ -86,8 +87,8 @@ private static class DriverWrapper { private final Object driverConfig; private DriverWrapper( - Class driverClass, - Object driverConfig + Class driverClass, + Object driverConfig ) { this.driverClass = driverClass; this.driverConfig = driverConfig; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java index 9d4cbbb82..1522bf175 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/rat_registry/RatVerifierDriverRegistry.java @@ -9,7 +9,7 @@ /** * A Rat Verifier Driver Registry * The User can register Driver implementation instances and its configurations to the registry - * + *

* The Idscpv2 protocol will select during the idscp handshake a Rat Verifier mechanism and will * check for this RatVerifier in this registry * @@ -18,12 +18,13 @@ public class RatVerifierDriverRegistry { private static RatVerifierDriverRegistry instance; private static final ConcurrentHashMap drivers - = new ConcurrentHashMap<>(); + = new ConcurrentHashMap<>(); - private RatVerifierDriverRegistry(){} + private RatVerifierDriverRegistry() { + } - public static RatVerifierDriverRegistry getInstance(){ - if (instance == null){ + public static RatVerifierDriverRegistry getInstance() { + if (instance == null) { instance = new RatVerifierDriverRegistry(); } return instance; @@ -39,7 +40,7 @@ public static RatVerifierDriverRegistry getInstance(){ * The finite state machine is registered as the communication partner for the RatVerifier. * The RatVerifier will be initialized with a configuration, if present. Then it is started. */ - public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmListener listener){ + public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmListener listener) { DriverWrapper driverWrapper = drivers.get(mechanism); try { @@ -60,17 +61,17 @@ public static RatVerifierDriver startRatVerifierDriver(String mechanism, FsmList * Register Rat Verifier driver and an optional configuration in the registry */ public void registerDriver( - String mechanism, - Class driverClass, - Object driverConfig - ){ + String mechanism, + Class driverClass, + Object driverConfig + ) { drivers.put(mechanism, new DriverWrapper(driverClass, driverConfig)); } /* * Unregister the driver from the registry */ - public void unregisterDriver(String instance){ + public void unregisterDriver(String instance) { drivers.remove(instance); } @@ -82,8 +83,8 @@ private static class DriverWrapper { private final Object driverConfig; private DriverWrapper( - Class driver, - Object driverConfig + Class driver, + Object driverConfig ) { this.driverClass = driver; this.driverConfig = driverConfig; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index ff409ea7f..1b33c3730 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -4,7 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CompletableFuture; /** * A secureChannel which is the secure underlying basis of the IDSCP2 protocol, @@ -16,64 +16,48 @@ public class SecureChannel implements SecureChannelListener { private static final Logger LOG = LoggerFactory.getLogger(SecureChannel.class); private final SecureChannelEndpoint endpoint; - private final CountDownLatch fsmLatch = new CountDownLatch(1); - private FsmListener fsm = null; + private final CompletableFuture fsmPromise = new CompletableFuture<>(); - public SecureChannel(SecureChannelEndpoint secureChannelEndpoint){ + public SecureChannel(SecureChannelEndpoint secureChannelEndpoint) { this.endpoint = secureChannelEndpoint; } /* * close the secure channel forever */ - public void close(){ + public void close() { endpoint.close(); } /* * Send data via the secure channel endpoint to the peer connector * - * return true if the data were sent successfully, else false + * return true if the data has been sent successfully, else false */ - public boolean send(byte[] msg){ + public boolean send(byte[] msg) { LOG.debug("Send message via secure channel"); return endpoint.send(msg); } @Override - public void onMessage(byte[] data){ - LOG.debug("New raw data were received via the secure channel"); - try { - fsmLatch.await(); - fsm.onMessage(data); - } catch (InterruptedException e){ - Thread.currentThread().interrupt(); - } + public void onMessage(byte[] data) { + LOG.debug("New raw data has been received via the secure channel"); + fsmPromise.thenAccept(fsmListener -> fsmListener.onMessage(data)); } @Override public void onError() { - //tell fsm an error occurred in secure channel - try { - fsmLatch.await(); - fsm.onError(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + // Tell fsm an error occurred in secure channel + fsmPromise.thenAccept(FsmListener::onError); } @Override public void onClose() { - //tell fsm secure channel received EOF - try { - fsmLatch.await(); - fsm.onClose(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + // Tell fsm secure channel received EOF + fsmPromise.thenAccept(FsmListener::onClose); } - public boolean isConnected(){ + public boolean isConnected() { return endpoint.isConnected(); } @@ -81,7 +65,6 @@ public boolean isConnected(){ * set the corresponding finite state machine */ public void setFsm(FsmListener fsm) { - this.fsm = fsm; - fsmLatch.countDown(); + fsmPromise.complete(fsm); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java index 77afc5e8a..eadaa39c5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelEndpoint.java @@ -21,7 +21,7 @@ public interface SecureChannelEndpoint { /* * Send data from the secure channel endpoint to the peer connector * - * return true when data was sent, else false + * return true when data has been sent, else false */ boolean send(byte[] bytes); diff --git a/idscp2/src/main/proto/idscpv2.proto b/idscp2/src/main/proto/idscpv2.proto index 196503c04..6ef30fd1b 100644 --- a/idscp2/src/main/proto/idscpv2.proto +++ b/idscp2/src/main/proto/idscpv2.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option java_package = "de.fhg.aisec.ids.messages"; +option java_package = "de.fhg.aisec.ids.idscp2.messages"; option java_outer_classname = "IDSCP2"; //IDSCP message frame diff --git a/idscp2/src/main/proto/tpm2dAttestation.proto b/idscp2/src/main/proto/tpm2dAttestation.proto index 74b9c3a69..a35025346 100644 --- a/idscp2/src/main/proto/tpm2dAttestation.proto +++ b/idscp2/src/main/proto/tpm2dAttestation.proto @@ -1,5 +1,5 @@ syntax = "proto2"; -option java_package = "de.fhg.aisec.ids.messages"; +option java_package = "de.fhg.aisec.ids.idscp2.messages"; option java_outer_classname = "Tpm2dAttestation"; // protobuf messages for communicating with TPM diff --git a/idscp2/src/main/resources/simplelogger.properties b/idscp2/src/main/resources/simplelogger.properties new file mode 100644 index 000000000..eafa2b0f4 --- /dev/null +++ b/idscp2/src/main/resources/simplelogger.properties @@ -0,0 +1 @@ +org.slf4j.simpleLogger.defaultLogLevel=debug \ No newline at end of file diff --git a/idscp2/src/test/resources/ssl/aisecconnector1-keystore.jks b/idscp2/src/main/resources/ssl/aisecconnector1-keystore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/aisecconnector1-keystore.jks rename to idscp2/src/main/resources/ssl/aisecconnector1-keystore.jks diff --git a/idscp2/src/test/resources/ssl/aisecconnector2-keystore.jks b/idscp2/src/main/resources/ssl/aisecconnector2-keystore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/aisecconnector2-keystore.jks rename to idscp2/src/main/resources/ssl/aisecconnector2-keystore.jks diff --git a/idscp2/src/test/resources/ssl/client-truststore_new.jks b/idscp2/src/main/resources/ssl/client-truststore_new.jks similarity index 100% rename from idscp2/src/test/resources/ssl/client-truststore_new.jks rename to idscp2/src/main/resources/ssl/client-truststore_new.jks diff --git a/idscp2/src/test/resources/ssl/consumer-core-keystore.jks b/idscp2/src/main/resources/ssl/consumer-core-keystore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/consumer-core-keystore.jks rename to idscp2/src/main/resources/ssl/consumer-core-keystore.jks diff --git a/idscp2/src/test/resources/ssl/consumer-core-truststore.jks b/idscp2/src/main/resources/ssl/consumer-core-truststore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/consumer-core-truststore.jks rename to idscp2/src/main/resources/ssl/consumer-core-truststore.jks diff --git a/idscp2/src/test/resources/ssl/consumer-core.cert b/idscp2/src/main/resources/ssl/consumer-core.cert similarity index 100% rename from idscp2/src/test/resources/ssl/consumer-core.cert rename to idscp2/src/main/resources/ssl/consumer-core.cert diff --git a/idscp2/src/test/resources/ssl/consumer-core.p12 b/idscp2/src/main/resources/ssl/consumer-core.p12 similarity index 100% rename from idscp2/src/test/resources/ssl/consumer-core.p12 rename to idscp2/src/main/resources/ssl/consumer-core.p12 diff --git a/idscp2/src/test/resources/ssl/provider-core-keystore.jks b/idscp2/src/main/resources/ssl/provider-core-keystore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/provider-core-keystore.jks rename to idscp2/src/main/resources/ssl/provider-core-keystore.jks diff --git a/idscp2/src/test/resources/ssl/provider-core-truststore.jks b/idscp2/src/main/resources/ssl/provider-core-truststore.jks similarity index 100% rename from idscp2/src/test/resources/ssl/provider-core-truststore.jks rename to idscp2/src/main/resources/ssl/provider-core-truststore.jks diff --git a/idscp2/src/test/resources/ssl/provider-core.cert b/idscp2/src/main/resources/ssl/provider-core.cert similarity index 100% rename from idscp2/src/test/resources/ssl/provider-core.cert rename to idscp2/src/main/resources/ssl/provider-core.cert diff --git a/idscp2/src/test/resources/ssl/provider-core.p12 b/idscp2/src/main/resources/ssl/provider-core.p12 similarity index 100% rename from idscp2/src/test/resources/ssl/provider-core.p12 rename to idscp2/src/main/resources/ssl/provider-core.p12 diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index e601c6a2a..bae9c249c 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -2,19 +2,13 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.SecurityRequirements; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import org.junit.Ignore; import org.junit.Test; + import static org.junit.Assert.*; public class DapsDriverTest { - //toDo add further junit tests - - private String getExpiredToken() { - return ""; - } @Test - @Ignore public void testValidToken() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -46,7 +40,6 @@ public void testValidToken() { } @Test - @Ignore public void testInvalidClient() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -67,7 +60,6 @@ public void testInvalidClient() { } @Test - @Ignore public void testInvalidUrlNonSecure() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -88,7 +80,6 @@ public void testInvalidUrlNonSecure() { } @Test - @Ignore public void testInvalidUrl404() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -109,7 +100,6 @@ public void testInvalidUrl404() { } @Test (expected = RuntimeException.class) - @Ignore public void testInvalidPassword1() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -124,11 +114,10 @@ public void testInvalidPassword1() { .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); - DapsDriver dapsDriver = new DefaultDapsDriver(config); + new DefaultDapsDriver(config); } @Test (expected = RuntimeException.class) - @Ignore public void testInvalidPassword2() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -143,11 +132,10 @@ public void testInvalidPassword2() { .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); - DapsDriver dapsDriver = new DefaultDapsDriver(config); + new DefaultDapsDriver(config); } @Test (expected = RuntimeException.class) - @Ignore public void testInvalidKeyAlias() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() @@ -162,11 +150,10 @@ public void testInvalidKeyAlias() { .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); - DapsDriver dapsDriver = new DefaultDapsDriver(config); + new DefaultDapsDriver(config); } @Test - @Ignore public void testInvalidAuditLogging() { DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() diff --git a/karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks b/karaf-assembly/src/main/resources/etc/idscp2/aisecconnector1-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8cac581c388491153679329a43ce082c6877ea64 GIT binary patch literal 2527 zcma)7c{tSD8=vo(rOY5ROvSaAvW@Q;W9<$ajeQA~J+ojcjL@Yd3?sU>a4(}|m+jh; zx}{vCv6gb_whA{(wh^w914=XpP8dEax+^LgL1F}pDffk2?b4s3UT zAhcMvQr6872pkG>U>l$~LR13*zyNiqBmlr6Fb?cv-KJ@&kq+ja7sO?NWIV!)lDM=O zThg^J9CI+W@tY}GMCmQHwPuFO4OMd*!6A0xpjm7WT$Jq;=N;vugZ0+`MTS{zD>ob%e25AL~8DpY!z+nh%`@Isikt8I|+syQq@DJ$T5ru^A<5_ z<5GeLvAa6URbw>9DO*ReBEe0gbu34*Fjx9Uw1SWO@vo@`CEw+zD;5@4)kIvL7DWQs z>wn}V55|=hni6%XxVPt3Q~Zu+g)Zh4m2{7jvk<(sXMOi0>Vx?uFT}5N6V;Whdf?h-# zF)%Ym?Y%C`pDCl%9kOP3iu>#0*-p=6vS#Wp2QWgGSEL>sbeek>pR_TDJ6rZL@3fQ$52GK0S*iZc4I!AjxXz z9ZS`(rv^gF&F^({3vtVYGQ?!#m2Zq_?N7?LzMDc;)-dT?x@B@Yr)RU*YcA$wtHB$` zW4`l;35;H~pFH;%w`hJk+2gp`J%NJe(K2t#lbkujMcn*G%N~o#@qzdTR{5Eduuznu zaa-d8WC4Dtn1=yNl6zgWkmFOeN~-PGaEfmj-CB;R{==+(@PLO=IJoj`)NNHl!NP-IW2ci9o%D z;`e$(i{u|?DCsBZCk^Gls^0;iKF3(BkAUESWDk)I5A%zNk4G&@i1J<=|rDKxcg?8b`JJUvrh;A*42y_ zO`nO8bz*v?x6g?FN}i;P_0t5~q&&`JLhA3N`)l#H*NVPBJ~!w3B|f5^$JL=eFQ~+eH!XiYI}F z5D4s=upnlG9Fgb(5hwtK0=q#m#7^}D%Y+p%06@VZpeX?b?nHdD%Va*re01^=4xG0nZ0FdmnT&-%}gEpi@(v+f^roH&% zUI#1VhTG`!^?Y?Cr8xb<_pMZPP8%yoY!3p%JMC#{FRPvEacVfR{WNO~F&m}UlocGF zG7~O%=5Nh9KkU^74LLNkDF1W(wPNYpX2@GDvsZQcKk1ED&(>9VrY^HD+-P$9w!wkL z!?w*{jc`Da0~us_>IB?WBV*&-Q;;-7*>Svea-JyX!WD=ZrRJ%lI#ON&#LD_uKf;42 z(yfd@8V|g;Y&2e6{tWPhE=HP0k`8k#* ziWjRVvz04*>r`keuZ|GlQ+^(=dS9o_EiVq^xKI%Q0u*zA^THQ72g(VbR!$s-gGs&Z zSx05Y69LI-udJ-ZhY?XH)~rE=t!Wk59uOBJ)sxI`;+`*8DeIB0+U=-4?o08S+?IUHMW&C-~{V*IT^|w0_=sy+!25y~J66OaoIXeT`3|at-9U8__5}t{{4hr&Rgt0>i z{}t;pOqgMi%P>&@DzS~bwo!5$G24jUMyYL--bUQNn^FLWI{ zI(_X2>9eX`jj#DAwSwUTF9md(%G;w@lV2Zy^Sm+csb*owj;iw0Bj^`FxKTT?rF^)^ zlz&xAU<_9rs!uhGbzFO*`^zKKYIm$>pi9i7OSx+nKcS}y#7%VY;d*{_{}Zc^dQZoE zWT}Kz61-k76P>5M-}b}uRIpwIW2PMWE-H$sj5G+AiE&fSef4pl+++mHKXHnOm9HOa zm>s=oQy#+pRQ-f`FS5ayvR35W)^RHF0OHIpj_wHm3g0$3lLuzR+9kffzq;>tzK;(h zr&(_oKJ`&#yUR$a4e7dDcq!SG$1tbpONmRd4^J$1DZPNN6y$1Pyv9;8RB%nIvx`Fs KwRVuWxBmm2L>qhn literal 0 HcmV?d00001 diff --git a/karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.jks b/karaf-assembly/src/main/resources/etc/idscp2/client-truststore_new.jks new file mode 100644 index 0000000000000000000000000000000000000000..998f04c7d601ba0540b4d4d15fe86bdcb7af0bbf GIT binary patch literal 1974 zcmezO_TO6u1_mZLW=c+EU|`Jf5m7g0V2#i-HLzr0V9qvZVoo<`V)9?W%*4pV#L2LU z@x9*Bv>WXPylk9WZ60mkc^Mg5Ss4tR47m+B*_cCF*o2u}Tn&W{1VJ1w9xk_{#L~Qs z{It{}LpcK(kRUUUsHaP?LQsBwi9$$fafyPnqk@rvp@o5*IIp3Fp@FfXp_!qPfl-t= zuQ8BoWCrC@#f~OMC1j^FvNA9?G4eAQG%<29H8CvpkK@{zD!3fL8WmPNPq_~x&Fw@qo$5yw>f^z%Zipp*lu$0)ca^by}UFXjJ-QyZ?{>+ZV)9WPPWv_2jS{fCjs&lH-W0AJn z^d`@i3n>%5^?q;5x~aP$C}VQp@AKi}X;aJWgPVg@UHk&fq9!lNkFaBXHhY0NA8+i_ z0|h1%t(fN-%nR$yK6gH$%}Ddu&jpRiqF$e_G?cswTARIFYr)q`)f4V%ADcNjK_c{Q z_q-7GTP|1ZCae^(R(4Tf{QLLpf@vwwp0dPEJAHcYPH;|SEiO$0XT+SFY+JMu8SxV^ zBfbM>#A}d@$jFEsg4{I8fF{5U2+Vv2MwZ|VXcA@MKtv{&F^~erGcc12gEBcde+QQ) z!Lm4^?6+E_C(QqrT35-%gSVdjJEkXlX2wb9;|r=H&qqG5@jDQwm3?>1vkmJM4k%n( zWv&{pG$U!(o-1X4P89uFp5kG)-PAZD(@k=FV1bFvhNg&8W6iMqlh41(Dg6<-eZFGO zN~O6gqQ3`)HTed1&Qp6Y(r*y`BceUJ`C-GRNBlWeWeayq(t8#haQL8tV;V2-&qF^h zo0Pr35$7su*`aXqw@F9hk+cPe1tJctZOfML_ddntp6}9fIC9deG*Ly7N>#??wqo-l z84qW^R&lRtdE3}~FXyK<>)157N;ibrNN7Cy_8h_%#>n1pqxPn8;3R< zu*_#?WMuI$a5Hd$@eP>TETCqjMyJrDyeHG|6o z!KqSj-)zyd{agKa!QYw;4yWw+wJm3*g11jl;{112E#n$j-WJx6t=(6%)q*aUGGw#; zy5KBQD;fNflWV%jv40{$Cu%Mn59m$5oqTVV=eg`$_O5mFERRlnzrL02cVNM#Bj2{L zt8KjXc+FOed5P!u`?=4S4b1Y%-??DNvK1R{JxO@1*&4G}H&rvC`l;9g`I=)%Z~u9) zG}_O%emwg|cZGCR_eZxl%g_5C^<^ZTee+9vMniO0Y-gh0r`;LVbKcZFJ($0dnWyoe zYrYYqA=e$%<_Ut+7Vmn}bu&WYORM6`YKBXK_xC*O*&X-8P$I!$Zrc3ySu?wxy5@h* jKJsPXQbv^>U)0#*vbc9$N>rMBDW~+|HRjd{yhWM-qpIG& literal 0 HcmV?d00001 From 05150cb5df0021ae639000e2d5dc73bea5377ff3 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Sun, 24 May 2020 17:54:39 +0200 Subject: [PATCH 080/237] Finalized camel IDSCP2 server component, added example route XML --- .../idscp2/server/Idscp2ServerComponent.java | 7 +++ .../idscp2/server/Idscp2ServerEndpoint.java | 28 +++++----- examples/route-examples/example-idscp2.xml | 51 +++++++++++++++++++ 3 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 examples/route-examples/example-idscp2.xml diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java index 5a7375185..38c9a7ce6 100644 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java @@ -42,6 +42,13 @@ public synchronized void addServer(int port, Idscp2Server server) { servers.put(port, server); } + public synchronized void removeServer(int port) { + final var server = servers.get(port); + if (server != null) { + servers.remove(port); + } + } + @Override protected synchronized void doStop() throws Exception { for (Idscp2Server s : servers.values()) { diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java index b82150b7f..0151a188b 100644 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java +++ b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java @@ -16,6 +16,7 @@ */ package de.fhg.aisec.ids.camel.idscp2.server; +import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent; import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; @@ -29,8 +30,6 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; -import de.fhg.aisec.ids.idscp2.example.RunTLSClient; -import de.fhg.aisec.ids.idscp2.example.RunTLSServer; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; @@ -66,11 +65,13 @@ public class Idscp2ServerEndpoint extends DefaultEndpoint implements Idscp2Endpo public Idscp2ServerEndpoint(String uri, String remaining, Idscp2ServerComponent component) { super(uri, component); - final var uriMatcher = URI_REGEX.matcher(remaining); - if (!uriMatcher.matches()) { - throw new IllegalArgumentException(remaining + " is not a valid URI."); + final var settings = Idscp2OsgiComponent.getSettings(); + + final var remainingMatcher = URI_REGEX.matcher(remaining); + if (!remainingMatcher.matches()) { + throw new IllegalArgumentException(remaining + " is not a valid URI remainder, must be \"host:port\"."); } - final var matchResult = uriMatcher.toMatchResult(); + final var matchResult = remainingMatcher.toMatchResult(); final var host = matchResult.group(1); final var port = Integer.parseInt(matchResult.group(2)); @@ -79,15 +80,17 @@ public Idscp2ServerEndpoint(String uri, String remaining, Idscp2ServerComponent serverSettings = new Idscp2Settings.Builder() .setHost(host) .setServerPort(port) - .setKeyStore(RunTLSClient.class.getClassLoader(). - getResource("ssl/aisecconnector1-keystore.jks").getPath()) - .setTrustStore(RunTLSServer.class.getClassLoader(). - getResource("ssl/client-truststore_new.jks").getPath()) + .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") + .setTrustStorePath("etc/idscp2/client-truststore_new.jks") .setCertificateAlias("1.0.1") .setDapsKeyAlias("1") - .setRatTimeoutDelay(14) + .setRatTimeoutDelay(300) .build(); + if(settings == null) { + throw new RuntimeException("Settings not available"); + } + DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") @@ -96,7 +99,7 @@ public Idscp2ServerEndpoint(String uri, String remaining, Idscp2ServerComponent .setKeyStorePassword(serverSettings.getKeyStorePassword()) .setTrustStorePassword(serverSettings.getTrustStorePassword()) .setKeyAlias(serverSettings.getDapsKeyAlias()) - .setDapsUrl("https://daps.aisec.fraunhofer.de") + .setDapsUrl(settings.getConnectorConfig().getDapsUrl()) .build(); DapsDriver dapsDriver = new DefaultDapsDriver(config); @@ -169,6 +172,7 @@ public synchronized void doStart() throws Idscp2Exception { public synchronized void doStop() { LOG.debug("Stopping IDSCP2 server endpoint " + getEndpointUri()); this.server.terminate(); + ((Idscp2ServerComponent) this.getComponent()).removeServer(this.serverSettings.getServerPort()); } } diff --git a/examples/route-examples/example-idscp2.xml b/examples/route-examples/example-idscp2.xml new file mode 100644 index 000000000..07c50dd8c --- /dev/null +++ b/examples/route-examples/example-idscp2.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PONG + + + + + + + From 00c2043b74f0acc3218e71d282dbe99d80af6902 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 11:16:17 +0200 Subject: [PATCH 081/237] Simplified configuration classes, some cleanup --- .../idscp2/example/Idscp2ClientInitiator.java | 8 +++--- .../idscp2/example/Idscp2ServerInitiator.java | 25 +++++++++-------- .../ids/idscp2/example/RunTLSClient.java | 3 +-- .../ids/idscp2/example/RunTLSServer.java | 2 +- .../configuration/AttestationConfig.java | 20 ++++++++++++-- .../configuration/Idscp2Configuration.java | 22 +++++++-------- .../configuration/Idscp2Settings.java | 27 +++++++++++++++++++ 7 files changed, 73 insertions(+), 34 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index dbf0223cb..c7419d64f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -29,6 +29,7 @@ public class Idscp2ClientInitiator implements Idscp2EndpointListener { public void init(Idscp2Settings settings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); + DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") @@ -58,12 +59,11 @@ public void init(Idscp2Settings settings) { Idscp2Configuration clientConfig = new Idscp2Configuration( this, + settings, dapsDriver, - secureChannelDriver, - settings.getExpectedAttestation(), - settings.getSupportedAttestation(), - settings.getRatTimeoutDelay() + secureChannelDriver ); + clientConfig.connect(settings); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index b71befe88..171bbc053 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -24,29 +24,30 @@ import java.nio.charset.StandardCharsets; - public class Idscp2ServerInitiator implements Idscp2EndpointListener { private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerInitiator.class); - public void init(Idscp2Settings serverSettings) { + public void init(Idscp2Settings settings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); DefaultDapsDriverConfig config = new DefaultDapsDriverConfig.Builder() .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") - .setKeyStorePath(serverSettings.getKeyStorePath()) - .setTrustStorePath(serverSettings.getTrustStorePath()) - .setKeyStorePassword(serverSettings.getKeyStorePassword()) - .setTrustStorePassword(serverSettings.getTrustStorePassword()) - .setKeyAlias(serverSettings.getDapsKeyAlias()) + .setKeyStorePath(settings.getKeyStorePath()) + .setTrustStorePath(settings.getTrustStorePath()) + .setKeyStorePassword(settings.getKeyStorePassword()) + .setTrustStorePassword(settings.getTrustStorePassword()) + .setKeyAlias(settings.getDapsKeyAlias()) .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); + DapsDriver dapsDriver = new DefaultDapsDriver(config); RatProverDriverRegistry.getInstance().registerDriver( "Dummy", RatProverDummy.class, null); RatVerifierDriverRegistry.getInstance().registerDriver( "Dummy", RatVerifierDummy.class, null); + RatProverDriverRegistry.getInstance().registerDriver( "TPM2d", TPM2dProver.class, new TPM2dProverConfig.Builder().build() @@ -56,16 +57,14 @@ public void init(Idscp2Settings serverSettings) { new TPM2dVerifierConfig.Builder().build() ); - Idscp2Configuration idscpServerConfig = new Idscp2Configuration( + Idscp2Configuration serverConfig = new Idscp2Configuration( this, + settings, dapsDriver, - secureChannelDriver, - serverSettings.getExpectedAttestation(), - serverSettings.getSupportedAttestation(), - serverSettings.getRatTimeoutDelay() + secureChannelDriver ); - Idscp2Server idscp2Server = idscpServerConfig.listen(serverSettings); + Idscp2Server idscp2Server = serverConfig.listen(settings); try { Thread.sleep(40_000); //run server for 2 minutes diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java index 3b1b52dbd..98d71595c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSClient.java @@ -2,11 +2,10 @@ import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; - public class RunTLSClient { public static void main(String[] args) { - //start client + Idscp2Settings settings = new Idscp2Settings.Builder() .setKeyStorePath(RunTLSClient.class.getClassLoader(). getResource("ssl/aisecconnector1-keystore.jks").getPath()) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java index 04812608f..da28471a5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/RunTLSServer.java @@ -7,7 +7,7 @@ public class RunTLSServer { public static void main(String[] argv) { Idscp2Settings settings = new Idscp2Settings.Builder() - .setKeyStorePath(RunTLSClient.class.getClassLoader(). + .setKeyStorePath(RunTLSServer.class.getClassLoader(). getResource("ssl/aisecconnector1-keystore.jks").getPath()) .setTrustStorePath(RunTLSServer.class.getClassLoader(). getResource("ssl/client-truststore_new.jks").getPath()) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java index 6c97a752f..8281b2e05 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/AttestationConfig.java @@ -1,5 +1,7 @@ package de.fhg.aisec.ids.idscp2.idscp_core.configuration; +import java.util.Arrays; + /** * Attestation configuration class, containing attestation suite for supported / expected * attestation types @@ -7,13 +9,27 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class AttestationConfig { + public final static String[] DEFAULT_RAT_MECHANISMS = new String[] {"Dummy", "TPM2d"}; + private final String[] ratMechanisms; public AttestationConfig() { - + this.ratMechanisms = DEFAULT_RAT_MECHANISMS; } public String[] getRatMechanisms() { - return new String[]{"Dummy", "TPM2d"}; + return ratMechanisms; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AttestationConfig that = (AttestationConfig) o; + return Arrays.equals(ratMechanisms, that.ratMechanisms); + } + + @Override + public int hashCode() { + return Arrays.hashCode(ratMechanisms); + } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java index 9ff5d8cf1..4dc185fa5 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java @@ -25,25 +25,19 @@ public class Idscp2Configuration implements SecureChannelInitListener { private static final Logger LOG = LoggerFactory.getLogger(Idscp2Configuration.class); private final Idscp2EndpointListener endpointListener; + private final Idscp2Settings settings; private final DapsDriver dapsDriver; private final SecureChannelDriver secureChannelDriver; - private final String[] localExpectedRatCipher; - private final String[] localSupportedRatCipher; - private final int ratTimeout; public Idscp2Configuration(Idscp2EndpointListener endpointListener, + Idscp2Settings settings, DapsDriver dapsDriver, - SecureChannelDriver secureChannelDriver, - AttestationConfig expectedAttestation, - AttestationConfig supportedAttestation, - int ratTimeout + SecureChannelDriver secureChannelDriver ) { this.endpointListener = endpointListener; + this.settings = settings; this.dapsDriver = dapsDriver; this.secureChannelDriver = secureChannelDriver; - this.localExpectedRatCipher = expectedAttestation.getRatMechanisms(); - this.localSupportedRatCipher = supportedAttestation.getRatMechanisms(); - this.ratTimeout = ratTimeout; } /** @@ -86,8 +80,12 @@ public synchronized void onSecureChannel(SecureChannel secureChannel, endpointListener.onError("IDSCP2 connect failed because no secure channel available"); } else { LOG.trace("A new secure channel for an IDSCP2 connection was established"); - FSM fsm = new FSM(secureChannel, dapsDriver, localSupportedRatCipher, - localExpectedRatCipher, ratTimeout); + FSM fsm = new FSM( + secureChannel, + dapsDriver, + settings.getSupportedAttestation().getRatMechanisms(), + settings.getExpectedAttestation().getRatMechanisms(), + settings.getRatTimeoutDelay()); try { // Blocking until handshake is done diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java index b2fa66ec9..6c22dda3f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java @@ -2,6 +2,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Objects; + /** * IDSCP2 configuration class, contains information about keyStore and TrustStores, * Attestation Types, host, DAPS, ... @@ -155,4 +157,29 @@ public int getRatTimeoutDelay() { return ratTimeoutDelay; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Idscp2Settings that = (Idscp2Settings) o; + return serverPort == that.serverPort && + ratTimeoutDelay == that.ratTimeoutDelay && + Objects.equals(host, that.host) && + Objects.equals(trustStorePath, that.trustStorePath) && + Objects.equals(trustStorePassword, that.trustStorePassword) && + Objects.equals(keyStorePath, that.keyStorePath) && + Objects.equals(keyStorePassword, that.keyStorePassword) && + Objects.equals(certificateAlias, that.certificateAlias) && + Objects.equals(dapsKeyAlias, that.dapsKeyAlias) && + Objects.equals(keyStoreKeyType, that.keyStoreKeyType) && + Objects.equals(supportedAttestation, that.supportedAttestation) && + Objects.equals(expectedAttestation, that.expectedAttestation); + } + + @Override + public int hashCode() { + return Objects.hash(serverPort, host, trustStorePath, trustStorePassword, keyStorePath, + keyStorePassword, certificateAlias, dapsKeyAlias, keyStoreKeyType, supportedAttestation, + expectedAttestation, ratTimeoutDelay); + } } From ef8c2217ecd4eebbe21c2bbc7d0fb4632f79887c Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 11:18:07 +0200 Subject: [PATCH 082/237] Disabled sporadically failing unit tests --- idscp2/src/test/java/DapsDriverTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index bae9c249c..6808ce21e 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -2,10 +2,12 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.SecurityRequirements; import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; +@Ignore("Some test rely on external server resources and are somewhat unreliable right now.") public class DapsDriverTest { @Test From bb2cbd2d58e01d434de165b61f84f1505d818a1c Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 11:22:26 +0200 Subject: [PATCH 083/237] Kotlin migration, server fixes --- camel-idscp2/build.gradle | 22 --- camel-idscp2/build.gradle.kts | 25 +++ .../ids/camel/idscp2/Idscp2OsgiComponent.java | 123 ------------ .../idscp2/server/Idscp2ServerComponent.java | 59 ------ .../idscp2/server/Idscp2ServerConsumer.java | 71 ------- .../idscp2/server/Idscp2ServerEndpoint.java | 178 ------------------ .../ids/camel/idscp2/Idscp2OsgiComponent.kt | 101 ++++++++++ .../camel/idscp2/server/CamelIdscp2Server.kt | 50 +++++ .../idscp2/server/Idscp2ServerComponent.kt | 91 +++++++++ .../idscp2/server/Idscp2ServerConsumer.kt | 64 +++++++ .../idscp2/server/Idscp2ServerEndpoint.kt | 124 ++++++++++++ .../idscp2/server/Idscp2ServerProducer.kt} | 27 +-- 12 files changed, 465 insertions(+), 470 deletions(-) delete mode 100644 camel-idscp2/build.gradle create mode 100644 camel-idscp2/build.gradle.kts delete mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java delete mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java delete mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java delete mode 100644 camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt rename camel-idscp2/src/main/{java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java => kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt} (57%) diff --git a/camel-idscp2/build.gradle b/camel-idscp2/build.gradle deleted file mode 100644 index ad2d9c165..000000000 --- a/camel-idscp2/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -description = 'Camel IDS Component' - -dependencies { - providedByBundle(project(':ids-api')) { transitive = false } - providedByBundle(project(':idscp2')) { transitive = false } - - // Bill of Materials (BOM) for Camel - bom group: 'org.apache.camel', name: 'camel-parent', version: libraryVersions.camel - - providedByFeature group: 'org.apache.camel', name: 'camel-core', version: libraryVersions.camel - - compileOnly group: 'org.checkerframework', name: 'checker-qual', version: libraryVersions.checkerQual - - osgiCore group: 'org.osgi', name: 'osgi.cmpn', version: libraryVersions.osgiCompendium - osgiCore group: 'org.osgi', name: 'org.osgi.core', version: libraryVersions.osgi - - providedByFeature group: 'com.google.protobuf', name: 'protobuf-java', version: libraryVersions.protobuf - - testImplementation group: 'junit', name: 'junit' - testImplementation group: 'org.apache.camel', name: 'camel-test', version: libraryVersions.camel - testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito -} diff --git a/camel-idscp2/build.gradle.kts b/camel-idscp2/build.gradle.kts new file mode 100644 index 000000000..aa84e4e55 --- /dev/null +++ b/camel-idscp2/build.gradle.kts @@ -0,0 +1,25 @@ +description = "Camel IDS Component" + +dependencies { + @Suppress("UNCHECKED_CAST") val libraryVersions = + rootProject.ext.get("libraryVersions") as Map + + providedByBundle(project(":ids-api")) { isTransitive = false } + providedByBundle(project(":idscp2")) { isTransitive = false } + + // Bill of Materials (BOM) for Camel + bom("org.apache.camel", "camel-parent", libraryVersions["camel"]) + + providedByFeature("org.apache.camel", "camel-core", libraryVersions["camel"]) + + compileOnly("org.checkerframework", "checker-qual", libraryVersions["checkerQual"]) + + osgiCore("org.osgi", "osgi.cmpn", libraryVersions["osgiCompendium"]) + osgiCore("org.osgi", "org.osgi.core", libraryVersions["osgi"]) + + providedByFeature("com.google.protobuf", "protobuf-java", libraryVersions["protobuf"]) + + testImplementation("junit", "junit", libraryVersions["junit4"]) + testImplementation("org.apache.camel", "camel-test", libraryVersions["camel"]) + testImplementation("org.mockito", "mockito-core", libraryVersions["mockito"]) +} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java deleted file mode 100644 index b6f204bcc..000000000 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.java +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * camel-ids - * %% - * Copyright (C) 2019 Fraunhofer AISEC - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ -package de.fhg.aisec.ids.camel.idscp2; - -import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager; -import de.fhg.aisec.ids.api.infomodel.InfoModel; -import de.fhg.aisec.ids.api.settings.Settings; -import de.fhg.aisec.ids.api.tokenm.TokenManager; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.osgi.service.component.annotations.*; - -@Component -public class Idscp2OsgiComponent { - - @Reference(cardinality = ReferenceCardinality.MANDATORY) - private Settings settings = null; - - @Reference(cardinality = ReferenceCardinality.MANDATORY) - private InfoModel infoModelManager = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private TokenManager tokenManager = null; - - @Reference(cardinality = ReferenceCardinality.OPTIONAL) - private EndpointConfigManager endpointConfigManager = null; - - private static Idscp2OsgiComponent instance; - - @Activate - @SuppressWarnings("squid:S2696") - protected void activate() { - instance = this; - } - - @Deactivate - @SuppressWarnings("squid:S2696") - protected void deactivate() { - instance = null; - } - - @Nullable - public static Settings getSettings() { - Idscp2OsgiComponent in = instance; - if (in != null) { - return in.settings; - } - return null; - } - - /** - * Is actually NonNull due to ReferenceCardinality.MANDATORY, - * but instance might be null for Unit Tests - * @return Info-Model-Manager instance - */ - @Nullable - public static InfoModel getInfoModelManager() { - Idscp2OsgiComponent in = instance; - if (in != null) { - return in.infoModelManager; - } - return null; - } - - /** - * Is actually NonNull due to ReferenceCardinality.MANDATORY, - * but instance might be null for Unit Tests - * @return Token-Manager instance - */ - @Nullable - public static TokenManager getTokenManager() { - Idscp2OsgiComponent in = instance; - if (in != null) { - return in.tokenManager; - } - return null; - } - - @Nullable - public static EndpointConfigManager getEndpointConfigManager() { - Idscp2OsgiComponent in = instance; - if (in != null) { - return in.endpointConfigManager; - } - return null; - } - - public void setSettings(Settings settings) { - this.settings = settings; - } - - public void setInfoModelManager(InfoModel infoModelManager) { - this.infoModelManager = infoModelManager; - } - - public void setTokenManager(TokenManager tokenManager) { - this.tokenManager = tokenManager; - } - - public void setEndpointConfigManager(EndpointConfigManager endpointConfigManager) { - this.endpointConfigManager = endpointConfigManager; - } - - public static void setInstance(Idscp2OsgiComponent instance) { - Idscp2OsgiComponent.instance = instance; - } -} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java deleted file mode 100644 index 38c9a7ce6..000000000 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package de.fhg.aisec.ids.camel.idscp2.server; - -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; -import org.apache.camel.Endpoint; -import org.apache.camel.spi.annotations.Component; -import org.apache.camel.support.DefaultComponent; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -@Component("idscp2server") -public class Idscp2ServerComponent extends DefaultComponent { - final Map servers = new ConcurrentHashMap<>(); - - public Idscp2ServerComponent() { - } - - @Override - protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { - Endpoint endpoint = new Idscp2ServerEndpoint(uri, remaining, this); - setProperties(endpoint, parameters); - return endpoint; - } - - public synchronized void addServer(int port, Idscp2Server server) { - servers.put(port, server); - } - - public synchronized void removeServer(int port) { - final var server = servers.get(port); - if (server != null) { - servers.remove(port); - } - } - - @Override - protected synchronized void doStop() throws Exception { - for (Idscp2Server s : servers.values()) { - s.terminate(); - } - super.doStop(); - } -} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java deleted file mode 100644 index ce5706cf2..000000000 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package de.fhg.aisec.ids.camel.idscp2.server; - -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener; -import org.apache.camel.Message; -import org.apache.camel.Processor; -import org.apache.camel.support.DefaultConsumer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The IDSCP2 server consumer. - */ -public class Idscp2ServerConsumer extends DefaultConsumer implements Idscp2MessageListener { - private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerConsumer.class); - private final Idscp2ServerEndpoint endpoint; - - public Idscp2ServerConsumer(final Idscp2ServerEndpoint endpoint, final Processor processor) { - super(endpoint, processor); - this.endpoint = endpoint; - } - - @Override - protected void doStart() throws Exception { - super.doStart(); - endpoint.addConsumer(this); - } - - @Override - protected void doStop() throws Exception { - endpoint.removeConsumer(this); - super.doStop(); - } - - @Override - public void onMessage(Idscp2Connection connection, String type, byte[] data) { - final var exchange = endpoint.createExchange(); - try { - this.createUoW(exchange); - // Set relevant information - exchange.getIn().setHeader("idscp2.type", type); - exchange.getIn().setBody(data, byte[].class); - // Do processing - getProcessor().process(exchange); - // Handle response - Message response = exchange.getMessage(); - String responseType = response.getHeader("idscp2.type", String.class); - connection.send(responseType, response.getBody(byte[].class)); - } catch (Exception e) { - LOG.error("Error in Idscp2ServerConsumer.onMessage()", e); - } finally { - this.doneUoW(exchange); - } - } -} diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java b/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java deleted file mode 100644 index 0151a188b..000000000 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package de.fhg.aisec.ids.camel.idscp2.server; - -import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent; -import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig; -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; -import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; -import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; -import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; -import org.apache.camel.Consumer; -import org.apache.camel.Processor; -import org.apache.camel.Producer; -import org.apache.camel.spi.UriEndpoint; -import org.apache.camel.support.DefaultEndpoint; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Pattern; - -@UriEndpoint( - scheme = "idscp2server", - title = "IDSCP2 Server Socket", - syntax = "idscp2server://host:port", - label = "ids" -) -public class Idscp2ServerEndpoint extends DefaultEndpoint implements Idscp2EndpointListener { - private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerEndpoint.class); - private static final Pattern URI_REGEX = Pattern.compile("(.*?):(\\d+)$"); - - private final Idscp2Configuration serverConfiguration; - private final Idscp2Settings serverSettings; - private Idscp2Server server; - private final Set consumers = new HashSet<>(); - - public Idscp2ServerEndpoint(String uri, String remaining, Idscp2ServerComponent component) { - super(uri, component); - final var settings = Idscp2OsgiComponent.getSettings(); - - final var remainingMatcher = URI_REGEX.matcher(remaining); - if (!remainingMatcher.matches()) { - throw new IllegalArgumentException(remaining + " is not a valid URI remainder, must be \"host:port\"."); - } - final var matchResult = remainingMatcher.toMatchResult(); - final var host = matchResult.group(1); - final var port = Integer.parseInt(matchResult.group(2)); - - SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); - - serverSettings = new Idscp2Settings.Builder() - .setHost(host) - .setServerPort(port) - .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") - .setTrustStorePath("etc/idscp2/client-truststore_new.jks") - .setCertificateAlias("1.0.1") - .setDapsKeyAlias("1") - .setRatTimeoutDelay(300) - .build(); - - if(settings == null) { - throw new RuntimeException("Settings not available"); - } - - DefaultDapsDriverConfig config = - new DefaultDapsDriverConfig.Builder() - .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") - .setKeyStorePath(serverSettings.getKeyStorePath()) - .setTrustStorePath(serverSettings.getTrustStorePath()) - .setKeyStorePassword(serverSettings.getKeyStorePassword()) - .setTrustStorePassword(serverSettings.getTrustStorePassword()) - .setKeyAlias(serverSettings.getDapsKeyAlias()) - .setDapsUrl(settings.getConnectorConfig().getDapsUrl()) - .build(); - DapsDriver dapsDriver = new DefaultDapsDriver(config); - - RatProverDriverRegistry.getInstance().registerDriver( - "Dummy", RatProverDummy.class, null); - RatVerifierDriverRegistry.getInstance().registerDriver( - "Dummy", RatVerifierDummy.class, null); - RatProverDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dProver.class, - new TPM2dProverConfig.Builder().build() - ); - RatVerifierDriverRegistry.getInstance().registerDriver( - "TPM2d", TPM2dVerifier.class, - new TPM2dVerifierConfig.Builder().build() - ); - - serverConfiguration = new Idscp2Configuration( - this, - dapsDriver, - secureChannelDriver, - serverSettings.getExpectedAttestation(), - serverSettings.getSupportedAttestation(), - serverSettings.getRatTimeoutDelay() - ); - } - - public synchronized void addConsumer(Idscp2ServerConsumer consumer) { - this.consumers.add(consumer); - this.server.getAllConnections().forEach(c -> c.addGenericMessageListener(consumer)); - } - - public synchronized void removeConsumer(Idscp2ServerConsumer consumer) { - this.consumers.remove(consumer); - this.server.getAllConnections().forEach(c -> c.removeGenericMessageListener(consumer)); - } - - public synchronized void sendMessage(String type, byte[] body) { - this.server.getAllConnections().forEach(connection -> connection.send(type, body)); - } - - @Override - public synchronized Producer createProducer() { - return new Idscp2ServerProducer(this); - } - - @Override - public synchronized Consumer createConsumer(Processor processor) { - return new Idscp2ServerConsumer(this, processor); - } - - @Override - public synchronized void onConnection(Idscp2Connection connection) { - LOG.debug("New IDSCP2 connection on " + getEndpointUri() + ", register consumer listeners"); - this.consumers.forEach(connection::addGenericMessageListener); - } - - @Override - public void onError(String error) { - LOG.error("Error in IDSCP2 server endpoint " + getEndpointUri() + ":\n" + error); - } - - @Override - public synchronized void doStart() throws Idscp2Exception { - LOG.debug("Starting IDSCP2 server endpoint " + getEndpointUri()); - this.server = serverConfiguration.listen(serverSettings); - ((Idscp2ServerComponent) this.getComponent()).addServer(this.serverSettings.getServerPort(), this.server); - } - - @Override - public synchronized void doStop() { - LOG.debug("Stopping IDSCP2 server endpoint " + getEndpointUri()); - this.server.terminate(); - ((Idscp2ServerComponent) this.getComponent()).removeServer(this.serverSettings.getServerPort()); - } - -} diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.kt new file mode 100644 index 000000000..142f0c1ae --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/Idscp2OsgiComponent.kt @@ -0,0 +1,101 @@ +/*- + * ========================LICENSE_START================================= + * camel-ids + * %% + * Copyright (C) 2019 Fraunhofer AISEC + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package de.fhg.aisec.ids.camel.idscp2 + +import de.fhg.aisec.ids.api.endpointconfig.EndpointConfigManager +import de.fhg.aisec.ids.api.infomodel.InfoModel +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.api.tokenm.TokenManager +import org.osgi.service.component.annotations.* + +@Component +class Idscp2OsgiComponent { + @Reference(cardinality = ReferenceCardinality.MANDATORY) + private lateinit var settings: Settings + + @Reference(cardinality = ReferenceCardinality.MANDATORY) + private lateinit var infoModelManager: InfoModel + + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + private var tokenManager: TokenManager? = null + + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + private var endpointConfigManager: EndpointConfigManager? = null + + @Activate + fun activate() { + instance = this + } + + @Deactivate + fun deactivate() { + instance = null + } + + fun setSettings(settings: Settings) { + this.settings = settings + } + + fun setInfoModelManager(infoModelManager: InfoModel) { + this.infoModelManager = infoModelManager + } + + fun setTokenManager(tokenManager: TokenManager?) { + this.tokenManager = tokenManager + } + + fun setEndpointConfigManager(endpointConfigManager: EndpointConfigManager?) { + this.endpointConfigManager = endpointConfigManager + } + + companion object { + private var instance: Idscp2OsgiComponent? = null + + fun setInstance(instance: Idscp2OsgiComponent?) { + Companion.instance = instance + } + + /** + * Is never null due to ReferenceCardinality.MANDATORY, + * but instance might be null for Unit Tests + * @return Token-Manager instance + */ + fun getSettings(): Settings { + return instance!!.settings + } + + /** + * Is never null due to ReferenceCardinality.MANDATORY, + * but instance might be null for Unit Tests + * @return Info-Model-Manager instance + */ + fun getInfoModelManager(): InfoModel { + return instance!!.infoModelManager + } + + fun getTokenManager(): TokenManager? { + return instance?.tokenManager + } + + fun getEndpointConfigManager(): EndpointConfigManager? { + return instance?.endpointConfigManager + } + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt new file mode 100644 index 000000000..f531083ff --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt @@ -0,0 +1,50 @@ +package de.fhg.aisec.ids.camel.idscp2.server + +import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings +import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server +import java.util.* + +class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener { + private val server: Idscp2Server + val listeners: MutableSet = Collections.synchronizedSet(HashSet()) + + init { + val dapsDriverConfig = DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(serverSettings.keyStorePath) + .setTrustStorePath(serverSettings.trustStorePath) + .setKeyStorePassword(serverSettings.keyStorePassword) + .setTrustStorePassword(serverSettings.trustStorePassword) + .setKeyAlias(serverSettings.dapsKeyAlias) + .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) + .build() + val serverConfiguration = Idscp2Configuration( + this, + serverSettings, + DefaultDapsDriver(dapsDriverConfig), + NativeTLSDriver() + ) + server = serverConfiguration.listen(serverSettings) + } + + override fun onConnection(connection: Idscp2Connection) { + listeners.forEach { it.onConnection(connection) } + } + + override fun onError(error: String) { + listeners.forEach { it.onError(error) } + } + + val allConnections: Set = server.allConnections + + fun terminate() { + server.terminate() + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt new file mode 100644 index 000000000..f6f732f80 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry +import org.apache.camel.Endpoint +import org.apache.camel.spi.annotations.Component +import org.apache.camel.support.DefaultComponent +import java.lang.IllegalStateException + +@Component("idscp2server") +class Idscp2ServerComponent : DefaultComponent() { + private val servers: MutableMap> = HashMap() + + init { + RatProverDriverRegistry.getInstance().registerDriver( + "Dummy", RatProverDummy::class.java, null) + RatVerifierDriverRegistry.getInstance().registerDriver( + "Dummy", RatVerifierDummy::class.java, null) + RatProverDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dProver::class.java, + TPM2dProverConfig.Builder().build() + ) + RatVerifierDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dVerifier::class.java, + TPM2dVerifierConfig.Builder().build() + ) + } + + override fun createEndpoint(uri: String, remaining: String, parameters: Map): Endpoint { + val endpoint: Endpoint = Idscp2ServerEndpoint(uri, remaining, this) + setProperties(endpoint, parameters) + return endpoint + } + + @Synchronized + fun getServer(serverSettings: Idscp2Settings): CamelIdscp2Server { + if (serverSettings in servers) { + servers[serverSettings]?.let { + servers[serverSettings] = Pair(it.first + 1, it.second) + return it.second + } ?: throw IllegalStateException("This should never happen, please inform developers of this error!") + } else { + val server = CamelIdscp2Server(serverSettings) + servers[serverSettings] = Pair(1, server) + return server + } + } + + @Synchronized + fun freeServer(serverSettings: Idscp2Settings) { + servers[serverSettings]?.let { + if (it.first > 1) { + servers[serverSettings] = Pair(it.first - 1, it.second) + } else { + it.second.terminate() + servers.remove(serverSettings) + } + } + } + + @Synchronized + override fun doStop() { + servers.values.parallelStream() + .forEach { it.second.terminate() } + servers.clear() + super.doStop() + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt new file mode 100644 index 000000000..6b053557d --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server + +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener +import org.apache.camel.Processor +import org.apache.camel.support.DefaultConsumer +import org.slf4j.LoggerFactory + +/** + * The IDSCP2 server consumer. + */ +class Idscp2ServerConsumer(private val endpoint: Idscp2ServerEndpoint, processor: Processor) : + DefaultConsumer(endpoint, processor), Idscp2MessageListener { + override fun doStart() { + super.doStart() + endpoint.addConsumer(this) + } + + override fun doStop() { + endpoint.removeConsumer(this) + super.doStop() + } + + override fun onMessage(connection: Idscp2Connection, type: String, data: ByteArray) { + val exchange = endpoint.createExchange() + try { + createUoW(exchange) + // Set relevant information + exchange.getIn().setHeader("idscp2.type", type) + exchange.getIn().setBody(data, ByteArray::class.java) + // Do processing + processor.process(exchange) + // Handle response + val response = exchange.message + val responseType = response.getHeader("idscp2.type", String::class.java) + connection.send(responseType, response.getBody(ByteArray::class.java)) + } catch (e: Exception) { + LOG.error("Error in Idscp2ServerConsumer.onMessage()", e) + } finally { + doneUoW(exchange) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(Idscp2ServerConsumer::class.java) + } + +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt new file mode 100644 index 000000000..7cb58bb04 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.server + +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry +import org.apache.camel.Processor +import org.apache.camel.Producer +import org.apache.camel.spi.UriEndpoint +import org.apache.camel.support.DefaultEndpoint +import org.slf4j.LoggerFactory +import java.util.* +import java.util.regex.Pattern + +@UriEndpoint( + scheme = "idscp2server", + title = "IDSCP2 Server Socket", + syntax = "idscp2server://host:port", + label = "ids" +) +class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2ServerComponent?) : + DefaultEndpoint(uri, component), Idscp2EndpointListener { + private val serverSettings: Idscp2Settings + private lateinit var server: CamelIdscp2Server + private val consumers: MutableSet = HashSet() + + init { + val remainingMatcher = URI_REGEX.matcher(remaining) + require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } + val matchResult = remainingMatcher.toMatchResult() + val host = matchResult.group(1) + val port = matchResult.group(2).toInt() + serverSettings = Idscp2Settings.Builder() + .setHost(host) + .setServerPort(port) + .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") + .setTrustStorePath("etc/idscp2/client-truststore_new.jks") + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") + .setRatTimeoutDelay(300) + .build() + } + + @Synchronized + fun addConsumer(consumer: Idscp2ServerConsumer) { + consumers.add(consumer) + server.allConnections.forEach { it.addGenericMessageListener(consumer) } + } + + @Synchronized + fun removeConsumer(consumer: Idscp2ServerConsumer) { + consumers.remove(consumer) + server.allConnections.forEach { it.removeGenericMessageListener(consumer) } + } + + @Synchronized + fun sendMessage(type: String, body: ByteArray) { + server.allConnections.forEach { it.send(type, body) } + } + + @Synchronized + override fun createProducer(): Producer { + return Idscp2ServerProducer(this) + } + + @Synchronized + override fun createConsumer(processor: Processor): org.apache.camel.Consumer { + return Idscp2ServerConsumer(this, processor) + } + + @Synchronized + override fun onConnection(connection: Idscp2Connection) { + LOG.debug("New IDSCP2 connection on $endpointUri, register consumer listeners") + consumers.forEach { connection.addGenericMessageListener(it) } + } + + override fun onError(error: String) { + LOG.error("Error in IDSCP2 server endpoint $endpointUri:\n$error") + } + + @Synchronized + public override fun doStart() { + LOG.debug("Starting IDSCP2 server endpoint $endpointUri") + server = (component as Idscp2ServerComponent).getServer(serverSettings) + // Add this endpoint to this server's Idscp2EndpointListener set + server.listeners += this + } + + @Synchronized + public override fun doStop() { + LOG.debug("Stopping IDSCP2 server endpoint $endpointUri") + // Remove this endpoint from the server's Idscp2EndpointListener set + server.listeners -= this + (component as Idscp2ServerComponent).freeServer(serverSettings) + } + + companion object { + private val LOG = LoggerFactory.getLogger(Idscp2ServerEndpoint::class.java) + private val URI_REGEX = Pattern.compile("(.*?):(\\d+)$") + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt similarity index 57% rename from camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java rename to camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt index 579279079..691a0f4b9 100644 --- a/camel-idscp2/src/main/java/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.java +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt @@ -14,29 +14,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.fhg.aisec.ids.camel.idscp2.server; +package de.fhg.aisec.ids.camel.idscp2.server -import org.apache.camel.Exchange; -import org.apache.camel.Message; -import org.apache.camel.support.DefaultProducer; +import org.apache.camel.Exchange +import org.apache.camel.support.DefaultProducer /** * The IDSCP2 server producer. * Sends each message to all clients connected to this server endpoint. */ -public class Idscp2ServerProducer extends DefaultProducer { - private final Idscp2ServerEndpoint endpoint; +class Idscp2ServerProducer(private val endpoint: Idscp2ServerEndpoint) : DefaultProducer(endpoint) { - public Idscp2ServerProducer(Idscp2ServerEndpoint endpoint) { - super(endpoint); - this.endpoint = endpoint; + override fun process(exchange: Exchange) { + val message = exchange.getIn() + val type = message.getHeader("idscp.type", String::class.java) + val body = message.getBody(ByteArray::class.java) + endpoint.sendMessage(type, body) } - @Override - public void process(Exchange exchange) { - Message message = exchange.getIn(); - String type = message.getHeader("idscp.type", String.class); - byte[] body = message.getBody(byte[].class); - endpoint.sendMessage(type, body); - } -} +} \ No newline at end of file From 49c48b735d362e4a5135d61c1f024df4d721994f Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 11:23:02 +0200 Subject: [PATCH 084/237] IDSCP2 camel client implementation --- .../idscp2/client/Idscp2ClientComponent.kt | 55 +++++++ .../idscp2/client/Idscp2ClientConsumer.kt | 64 +++++++++ .../idscp2/client/Idscp2ClientEndpoint.kt | 135 ++++++++++++++++++ .../idscp2/client/Idscp2ClientProducer.kt | 35 +++++ .../idscp2/server/Idscp2ServerEndpoint.kt | 26 ++-- .../org/apache/camel/component/idscp2client | 2 +- 6 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientComponent.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientComponent.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientComponent.kt new file mode 100644 index 000000000..5ff106b07 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientComponent.kt @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.client + +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry +import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry +import org.apache.camel.Endpoint +import org.apache.camel.spi.annotations.Component +import org.apache.camel.support.DefaultComponent + +@Component("idscp2server") +class Idscp2ClientComponent : DefaultComponent() { + + init { + RatProverDriverRegistry.getInstance().registerDriver( + "Dummy", RatProverDummy::class.java, null) + RatVerifierDriverRegistry.getInstance().registerDriver( + "Dummy", RatVerifierDummy::class.java, null) + RatProverDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dProver::class.java, + TPM2dProverConfig.Builder().build() + ) + RatVerifierDriverRegistry.getInstance().registerDriver( + "TPM2d", TPM2dVerifier::class.java, + TPM2dVerifierConfig.Builder().build() + ) + } + + override fun createEndpoint(uri: String, remaining: String, parameters: Map): Endpoint { + val endpoint: Endpoint = Idscp2ClientEndpoint(uri, remaining, this) + setProperties(endpoint, parameters) + return endpoint + } + +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt new file mode 100644 index 000000000..13d6a27e4 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.client + +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener +import org.apache.camel.Processor +import org.apache.camel.support.DefaultConsumer +import org.slf4j.LoggerFactory + +/** + * The IDSCP2 server consumer. + */ +class Idscp2ClientConsumer(private val endpoint: Idscp2ClientEndpoint, processor: Processor) : + DefaultConsumer(endpoint, processor), Idscp2MessageListener { + override fun doStart() { + super.doStart() + endpoint.addConsumer(this) + } + + override fun doStop() { + endpoint.removeConsumer(this) + super.doStop() + } + + override fun onMessage(connection: Idscp2Connection, type: String, data: ByteArray) { + val exchange = endpoint.createExchange() + try { + createUoW(exchange) + // Set relevant information + exchange.getIn().setHeader("idscp2.type", type) + exchange.getIn().setBody(data, ByteArray::class.java) + // Do processing + processor.process(exchange) + // Handle response + val response = exchange.message + val responseType = response.getHeader("idscp2.type", String::class.java) + connection.send(responseType, response.getBody(ByteArray::class.java)) + } catch (e: Exception) { + LOG.error("Error in Idscp2ServerConsumer.onMessage()", e) + } finally { + doneUoW(exchange) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(Idscp2ClientConsumer::class.java) + } + +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt new file mode 100644 index 000000000..52a4ec275 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.client + +import de.fhg.aisec.ids.api.settings.Settings +import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent +import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig +import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings +import org.apache.camel.Processor +import org.apache.camel.Producer +import org.apache.camel.spi.UriEndpoint +import org.apache.camel.support.DefaultEndpoint +import org.slf4j.LoggerFactory +import java.util.* +import java.util.regex.Pattern + +@UriEndpoint( + scheme = "idscp2client", + title = "IDSCP2 Client Socket", + syntax = "idscp2client://host:port", + label = "ids" +) +class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2ClientComponent?) : + DefaultEndpoint(uri, component), Idscp2EndpointListener { + private val clientConfiguration: Idscp2Configuration + private val clientSettings: Idscp2Settings + private var connection: Idscp2Connection? = null + private val consumers: MutableSet = HashSet() + + init { + val settings: Settings = Idscp2OsgiComponent.getSettings() + val remainingMatcher = URI_REGEX.matcher(remaining) + require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } + val matchResult = remainingMatcher.toMatchResult() + val host = matchResult.group(1) + val port = matchResult.group(2).toInt() + clientSettings = Idscp2Settings.Builder() + .setHost(host) + .setServerPort(port) + .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") + .setTrustStorePath("etc/idscp2/client-truststore_new.jks") + .setCertificateAlias("1.0.1") + .setDapsKeyAlias("1") + .setRatTimeoutDelay(300) + .build() + val config = DefaultDapsDriverConfig.Builder() + .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setKeyStorePath(clientSettings.keyStorePath) + .setTrustStorePath(clientSettings.trustStorePath) + .setKeyStorePassword(clientSettings.keyStorePassword) + .setTrustStorePassword(clientSettings.trustStorePassword) + .setKeyAlias(clientSettings.dapsKeyAlias) + .setDapsUrl(settings.connectorConfig.dapsUrl) + .build() + clientConfiguration = Idscp2Configuration( + this, + clientSettings, + DefaultDapsDriver(config), + NativeTLSDriver() + ) + } + + @Synchronized + fun addConsumer(consumer: Idscp2ClientConsumer) { + consumers.add(consumer) + connection?.addGenericMessageListener(consumer) + } + + @Synchronized + fun removeConsumer(consumer: Idscp2ClientConsumer) { + consumers.remove(consumer) + connection?.removeGenericMessageListener(consumer) + } + + @Synchronized + fun sendMessage(type: String, body: ByteArray) { + connection?.send(type, body) + } + + @Synchronized + override fun createProducer(): Producer { + return Idscp2ClientProducer(this) + } + + @Synchronized + override fun createConsumer(processor: Processor): org.apache.camel.Consumer { + return Idscp2ClientConsumer(this, processor) + } + + @Synchronized + override fun onConnection(connection: Idscp2Connection) { + LOG.debug("New IDSCP2 connection on $endpointUri, register consumer listeners") + consumers.forEach { connection.addGenericMessageListener(it) } + } + + override fun onError(error: String) { + LOG.error("Error in IDSCP2 client endpoint $endpointUri:\n$error") + } + + @Synchronized + public override fun doStart() { + LOG.debug("Starting IDSCP2 client endpoint $endpointUri") + clientConfiguration.connect(clientSettings) + } + + @Synchronized + public override fun doStop() { + LOG.debug("Stopping IDSCP2 client endpoint $endpointUri") + connection?.close() + } + + companion object { + private val LOG = LoggerFactory.getLogger(Idscp2ClientEndpoint::class.java) + private val URI_REGEX = Pattern.compile("(.*?):(\\d+)$") + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt new file mode 100644 index 000000000..380ae3f28 --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2.client + +import org.apache.camel.Exchange +import org.apache.camel.support.DefaultProducer + +/** + * The IDSCP2 server producer. + * Sends each message to all clients connected to this server endpoint. + */ +class Idscp2ClientProducer(private val endpoint: Idscp2ClientEndpoint) : DefaultProducer(endpoint) { + + override fun process(exchange: Exchange) { + val message = exchange.getIn() + val type = message.getHeader("idscp2.type", String::class.java) + val body = message.getBody(ByteArray::class.java) + endpoint.sendMessage(type, body) + } + +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt index 7cb58bb04..b75b13056 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt @@ -17,16 +17,8 @@ package de.fhg.aisec.ids.camel.idscp2.server import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProverConfig -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier -import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings -import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry -import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry import org.apache.camel.Processor import org.apache.camel.Producer import org.apache.camel.spi.UriEndpoint @@ -44,7 +36,7 @@ import java.util.regex.Pattern class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2ServerComponent?) : DefaultEndpoint(uri, component), Idscp2EndpointListener { private val serverSettings: Idscp2Settings - private lateinit var server: CamelIdscp2Server + private var server: CamelIdscp2Server? = null private val consumers: MutableSet = HashSet() init { @@ -67,18 +59,18 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser @Synchronized fun addConsumer(consumer: Idscp2ServerConsumer) { consumers.add(consumer) - server.allConnections.forEach { it.addGenericMessageListener(consumer) } + server?.let { server -> server.allConnections.forEach { it.addGenericMessageListener(consumer) } } } @Synchronized fun removeConsumer(consumer: Idscp2ServerConsumer) { + server?.let { server -> server.allConnections.forEach { it.removeGenericMessageListener(consumer) } } consumers.remove(consumer) - server.allConnections.forEach { it.removeGenericMessageListener(consumer) } } @Synchronized fun sendMessage(type: String, body: ByteArray) { - server.allConnections.forEach { it.send(type, body) } + server?.let { server -> server.allConnections.forEach { it.send(type, body) } } } @Synchronized @@ -104,16 +96,18 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser @Synchronized public override fun doStart() { LOG.debug("Starting IDSCP2 server endpoint $endpointUri") - server = (component as Idscp2ServerComponent).getServer(serverSettings) - // Add this endpoint to this server's Idscp2EndpointListener set - server.listeners += this + (component as Idscp2ServerComponent).getServer(serverSettings).let { + server = it + // Add this endpoint to this server's Idscp2EndpointListener set + it.listeners += this + } } @Synchronized public override fun doStop() { LOG.debug("Stopping IDSCP2 server endpoint $endpointUri") // Remove this endpoint from the server's Idscp2EndpointListener set - server.listeners -= this + server?.let { it.listeners -= this } (component as Idscp2ServerComponent).freeServer(serverSettings) } diff --git a/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client index 57aaa95c7..f0e6faab9 100644 --- a/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client +++ b/camel-idscp2/src/main/resources/META-INF/services/org/apache/camel/component/idscp2client @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -class=de.fhg.aisec.ids.camel.idscp2.client.WsComponent +class=de.fhg.aisec.ids.camel.idscp2.client.Idscp2ClientComponent From 350cc622b580803731139d371c49637ef881b3a9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 13:53:38 +0200 Subject: [PATCH 085/237] Fixed error handling to "fail fast", handlers for async errors only --- .../ids/idscp2/Idscp2EndpointListener.java | 2 +- .../secure_channel/NativeTLSDriver.java | 3 +- .../client/DataAvailableListener.java | 2 +- .../client/InputListenerThread.java | 2 +- .../secure_channel/client/TLSClient.java | 21 ++---- .../secure_channel/server/TLSServer.java | 3 +- .../server/TLSServerThread.java | 15 +++-- .../interfaces/SecureChannelDriver.java | 3 +- .../idscp2/example/Idscp2ClientInitiator.java | 8 +-- .../idscp2/example/Idscp2ServerInitiator.java | 8 +-- .../idscp2/idscp_core/Idscp2Connection.java | 4 ++ .../idscp_core/Idscp2ConnectionAdapter.java | 2 +- .../idscp_core/Idscp2ConnectionListener.java | 2 +- .../configuration/Idscp2Configuration.java | 65 +++++++++---------- .../SecureChannelInitListener.java | 2 + .../idscp_core/finite_state_machine/FSM.java | 4 +- .../finite_state_machine/FsmListener.java | 2 +- .../secure_channel/SecureChannel.java | 4 +- .../secure_channel/SecureChannelListener.java | 2 +- 19 files changed, 75 insertions(+), 79 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java index dda504f89..08c8f9077 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/Idscp2EndpointListener.java @@ -18,5 +18,5 @@ public interface Idscp2EndpointListener { /* * Called when an error occurred in the underlying IDSCP2 protocol */ - void onError(String error); + void onError(Throwable t); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 1a2500856..674ddc9e0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -33,8 +33,7 @@ public void connect(Idscp2Settings settings, SecureChannelInitListener channelIn TLSClient tlsClient = new TLSClient(settings, channelInitListener); tlsClient.connect(settings.getHost(), settings.getServerPort()); } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) { - LOG.error("Call to connect() has failed", e); - channelInitListener.onSecureChannel(null, null); + throw new Idscp2Exception("Call to connect() has failed", e); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java index c0101dcf3..c59b4c912 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/DataAvailableListener.java @@ -16,7 +16,7 @@ public interface DataAvailableListener { /* * Notify listener that an error has occurred */ - void onError(); + void onError(Throwable e); /* * Notify listener that the socket has been closed diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 3874c8c8f..49f9f6302 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -42,7 +42,7 @@ public void run() { listener.onClose(); running = false; //terminate } catch (IOException e) { - listener.onError(); + listener.onError(e); running = false; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index dfead2cbe..01616a4e1 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -3,6 +3,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; +import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; @@ -87,9 +88,7 @@ public TLSClient(Idscp2Settings clientSettings, SecureChannelInitListener secure public void connect(String hostname, int port) { SSLSocket sslSocket = (SSLSocket) clientSocket; if (sslSocket == null || sslSocket.isClosed()) { - LOG.warn("Client socket is not available"); - secureChannelInitListener.onSecureChannel(null, null); - return; + throw new Idscp2Exception("Client socket is not available"); } try { @@ -111,13 +110,11 @@ public void connect(String hostname, int port) { LOG.debug("Start TLS Handshake"); sslSocket.startHandshake(); } catch (SSLHandshakeException | SSLProtocolException e) { - LOG.warn("TLS Handshake failed: {}", e.getMessage()); disconnect(); - secureChannelInitListener.onSecureChannel(null, null); + throw new Idscp2Exception("TLS Handshake failed", e); } catch (IOException e) { - LOG.error("Connecting TLS client to server failed " + e.getMessage()); disconnect(); - secureChannelInitListener.onSecureChannel(null, null); + throw new Idscp2Exception("Connecting TLS client to server failed", e); } } @@ -143,8 +140,8 @@ public void onClose() { } @Override - public void onError() { - listenerPromise.thenAccept(SecureChannelListener::onError); + public void onError(Throwable t) { + listenerPromise.thenAccept(secureChannelListener -> secureChannelListener.onError(t)); } @Override @@ -187,12 +184,8 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) TLSSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); LOG.debug("TLS session is valid"); } catch (SSLPeerUnverifiedException e) { - if (LOG.isWarnEnabled()) { - LOG.warn("TLS session is not valid. Close TLS connection", e); - } disconnect(); - secureChannelInitListener.onSecureChannel(null, null); - return; + throw new Idscp2Exception("TLS session is not valid. Close TLS connection", e); } // Create secure channel, register secure channel as message listener and notify IDSCP2 Configuration. diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index 254d3f328..f172c53da 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -116,7 +116,8 @@ public void run() { LOG.debug("Server socket has been closed."); isRunning = false; } catch (IOException e) { - LOG.error("TLS server socket accept failed", e); + LOG.error("Error during TLS server socket accept, notifying error handlers..."); + secureChannelInitListener.onError(e); isRunning = false; } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java index b513d0989..480410f61 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServerThread.java @@ -58,8 +58,9 @@ public void run() { sslSocket.startHandshake(); // Wait for TLS session verification tlsVerificationLatch.await(); - } catch (IOException e) { - LOG.warn("Exception occurred during SSL handshake. Quiting server thread...", e); + } catch (Exception e) { + LOG.error("Exception occurred during SSL handshake. Quiting server thread...", e); + onError(e); running = false; } @@ -77,7 +78,7 @@ public void run() { onClose(); running = false; } catch (IOException e) { - onError(); + onError(e); running = false; } } @@ -104,10 +105,10 @@ public boolean send(byte[] data) { out.writeInt(data.length); out.write(data); out.flush(); - LOG.trace("Send message: " + new String(data)); + LOG.trace("Sent message: " + new String(data)); return true; } catch (IOException e) { - LOG.error("ServerThread cannot send data."); + LOG.error("Server could not send data."); closeSockets(); return false; } @@ -118,8 +119,8 @@ private void onClose() { channelListenerPromise.thenAccept(SecureChannelListener::onClose); } - private void onError() { - channelListenerPromise.thenAccept(SecureChannelListener::onError); + private void onError(Throwable t) { + channelListenerPromise.thenAccept(secureChannelListener -> secureChannelListener.onError(t)); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index 09c8202cf..ac954f550 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -1,6 +1,5 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; -import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; @@ -24,5 +23,5 @@ public interface SecureChannelDriver { * Starting a secure server */ SecureServer listen(Idscp2Settings settings, SecureChannelInitListener channelInitListener, - CompletableFuture serverListenerPromise) throws Idscp2Exception; + CompletableFuture serverListenerPromise); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index c7419d64f..07b580f40 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -72,8 +72,8 @@ public void onConnection(Idscp2Connection connection) { System.out.println("Client: New connection with id " + connection.getId()); connection.addConnectionListener(new Idscp2ConnectionAdapter() { @Override - public void onError(String error) { - LOG.error("Client connection error occurred: " + error); + public void onError(Throwable t) { + LOG.error("Client connection error occurred", t); } @Override @@ -92,7 +92,7 @@ public void onClose(Idscp2Connection connection) { } @Override - public void onError(String error) { - LOG.error("Client endpoint error occurred: " + error); + public void onError(Throwable t) { + LOG.error("Client endpoint error occurred", t); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index 171bbc053..960a477f6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -79,8 +79,8 @@ public void onConnection(Idscp2Connection connection) { System.out.println("Server: New connection with id " + connection.getId()); connection.addConnectionListener(new Idscp2ConnectionAdapter() { @Override - public void onError(String error) { - LOG.error("Server connection error occurred: " + error); + public void onError(Throwable t) { + LOG.error("Server connection error occurred", t); } @Override @@ -98,7 +98,7 @@ public void onClose(Idscp2Connection connection) { } @Override - public void onError(String error) { - LOG.error("Server endpoint error occurred: " + error); + public void onError(Throwable t) { + LOG.error("Server endpoint error occurred", t); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index 4451794ce..74dc49f6b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -65,6 +65,10 @@ public void onMessage(String type, byte[] msg) { } } + public void onError(Throwable t) { + connectionListeners.forEach(idscp2ConnectionListener -> idscp2ConnectionListener.onError(t)); + } + public void onClose() { LOG.debug("Connection with id {} has been closed, notify listeners", connectionId); connectionListeners.forEach(l -> l.onClose(this)); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java index 9588fe687..d45391ea8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java @@ -3,7 +3,7 @@ public class Idscp2ConnectionAdapter implements Idscp2ConnectionListener { @Override - public void onError(String error) { + public void onError(Throwable t) { } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java index 40bd19b1c..83a020c40 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionListener.java @@ -6,7 +6,7 @@ */ public interface Idscp2ConnectionListener { - void onError(String error); + void onError(Throwable t); void onClose(Idscp2Connection connection); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java index 4dc185fa5..57d871d1b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java @@ -75,45 +75,40 @@ public Idscp2Server listen(Idscp2Settings settings) throws Idscp2Exception { @Override public synchronized void onSecureChannel(SecureChannel secureChannel, CompletableFuture serverListenerPromise) { - if (secureChannel == null) { - LOG.warn("IDSCP2 connect failed because no secure channel available"); - endpointListener.onError("IDSCP2 connect failed because no secure channel available"); - } else { - LOG.trace("A new secure channel for an IDSCP2 connection was established"); - FSM fsm = new FSM( - secureChannel, - dapsDriver, - settings.getSupportedAttestation().getRatMechanisms(), - settings.getExpectedAttestation().getRatMechanisms(), - settings.getRatTimeoutDelay()); + LOG.trace("A new secure channel for an IDSCP2 connection was established"); + FSM fsm = new FSM( + secureChannel, + dapsDriver, + settings.getSupportedAttestation().getRatMechanisms(), + settings.getExpectedAttestation().getRatMechanisms(), + settings.getRatTimeoutDelay()); - try { - // Blocking until handshake is done - fsm.startIdscpHandshake(); - } catch (Idscp2Exception e) { - return; - } + fsm.startIdscpHandshake(); - String connectionId = UUID.randomUUID().toString(); - // Threads calling onMessage() will be blocked until all listeners have been registered, see below - Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); - fsm.registerConnection(newConnection); - LOG.debug("A new IDSCP2 connection with id {} was created", connectionId); - if (serverListenerPromise != null) { - // Complete the connection promise for the IDSCP server - serverListenerPromise.thenAccept(serverListener -> { - serverListener.onConnectionCreated(newConnection); - newConnection.addConnectionListener(new Idscp2ConnectionAdapter() { - @Override - public void onClose(Idscp2Connection connection) { - serverListener.onConnectionClose(connection); - } - }); + String connectionId = UUID.randomUUID().toString(); + // Threads calling onMessage() will be blocked until all listeners have been registered, see below + Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); + fsm.registerConnection(newConnection); + LOG.debug("A new IDSCP2 connection with id {} was created", connectionId); + if (serverListenerPromise != null) { + // Complete the connection promise for the IDSCP server + serverListenerPromise.thenAccept(serverListener -> { + serverListener.onConnectionCreated(newConnection); + newConnection.addConnectionListener(new Idscp2ConnectionAdapter() { + @Override + public void onClose(Idscp2Connection connection) { + serverListener.onConnectionClose(connection); + } }); - } - endpointListener.onConnection(newConnection); - newConnection.unlockMessaging(); + }); } + endpointListener.onConnection(newConnection); + newConnection.unlockMessaging(); + } + + @Override + public void onError(Throwable t) { + endpointListener.onError(t); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java index 2af24aa22..9c733f7a8 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/SecureChannelInitListener.java @@ -21,4 +21,6 @@ void onSecureChannel( CompletableFuture serverListenerPromise ); + void onError(Throwable t); + } \ No newline at end of file diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 0b797578f..07a7158cd 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -429,7 +429,9 @@ boolean sendFromFSM(IdscpMessage msg) { * driver implementations */ @Override - public void onError() { + public void onError(Throwable t) { + // Broadcast the error to the respective listeners + connection.onError(t); //check for incorrect usage checkForFsmCircles(); diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java index 3b2b322c8..673631110 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FsmListener.java @@ -27,7 +27,7 @@ public interface FsmListener { /* * A method for providing internal errors to the fsm */ - void onError(); + void onError(Throwable t); /* * A method for notifying the fsm about closure of the secure channel diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index 1b33c3730..ffae9c55a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -46,9 +46,9 @@ public void onMessage(byte[] data) { } @Override - public void onError() { + public void onError(Throwable t) { // Tell fsm an error occurred in secure channel - fsmPromise.thenAccept(FsmListener::onError); + fsmPromise.thenAccept(fsmListener -> fsmListener.onError(t)); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java index 024f397e2..06efc83e0 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannelListener.java @@ -13,7 +13,7 @@ public interface SecureChannelListener { /* * Delegate an error from an secure channel endpoint to the secure channel */ - void onError(); + void onError(Throwable t); /* * Notify secure channel that secure channel endpoint has been closed From f3de18c3d9754f228697d0d22c0bef76cdf4e19b Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Tue, 26 May 2020 14:23:56 +0200 Subject: [PATCH 086/237] Separated example routes --- .../route-examples/example-idscp2-client.xml | 25 +++++++++ .../route-examples/example-idscp2-server.xml | 24 +++++++++ examples/route-examples/example-idscp2.xml | 51 ------------------- 3 files changed, 49 insertions(+), 51 deletions(-) create mode 100644 examples/route-examples/example-idscp2-client.xml create mode 100644 examples/route-examples/example-idscp2-server.xml delete mode 100644 examples/route-examples/example-idscp2.xml diff --git a/examples/route-examples/example-idscp2-client.xml b/examples/route-examples/example-idscp2-client.xml new file mode 100644 index 000000000..eb7569ffd --- /dev/null +++ b/examples/route-examples/example-idscp2-client.xml @@ -0,0 +1,25 @@ + + + + + + + + + PING + + + ping + + + + + + + + + diff --git a/examples/route-examples/example-idscp2-server.xml b/examples/route-examples/example-idscp2-server.xml new file mode 100644 index 000000000..44f24e692 --- /dev/null +++ b/examples/route-examples/example-idscp2-server.xml @@ -0,0 +1,24 @@ + + + + + + + + + + PONG + + + pong + + + + + + + diff --git a/examples/route-examples/example-idscp2.xml b/examples/route-examples/example-idscp2.xml deleted file mode 100644 index 07c50dd8c..000000000 --- a/examples/route-examples/example-idscp2.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PONG - - - - - - - From cf813db503a8c64fc35bdbd9442425664396926b Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 01:16:00 +0200 Subject: [PATCH 087/237] Separated "connection factories", Future-based client connection handling --- .../secure_channel/NativeTLSDriver.java | 10 ++- .../secure_channel/client/TLSClient.java | 32 ++++---- .../interfaces/SecureChannelDriver.java | 3 +- .../idscp2/example/Idscp2ClientInitiator.java | 69 ++++++++-------- .../idscp2/example/Idscp2ServerInitiator.java | 16 ++-- .../idscp2/idscp_core/Idscp2Connection.java | 24 +++++- .../configuration/Idscp2ClientFactory.java | 37 +++++++++ ...guration.java => Idscp2ServerFactory.java} | 52 ++++--------- .../configuration/Idscp2Settings.java | 2 +- .../idscp_core/finite_state_machine/FSM.java | 78 +++++++++---------- .../finite_state_machine/StateClosed.java | 27 +++++-- .../StateWaitForHello.java | 2 +- 12 files changed, 194 insertions(+), 158 deletions(-) create mode 100644 idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ClientFactory.java rename idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/{Idscp2Configuration.java => Idscp2ServerFactory.java} (65%) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java index 674ddc9e0..98582b0ba 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/NativeTLSDriver.java @@ -2,9 +2,11 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.client.TLSClient; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.server.TLSServer; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureServer; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; @@ -28,12 +30,14 @@ public class NativeTLSDriver implements SecureChannelDriver { * Performs an asynchronous client connect to a TLS server. */ @Override - public void connect(Idscp2Settings settings, SecureChannelInitListener channelInitListener) { + public void connect(Idscp2Settings settings, + DapsDriver dapsDriver, + CompletableFuture connectionFuture) { try { - TLSClient tlsClient = new TLSClient(settings, channelInitListener); + TLSClient tlsClient = new TLSClient(settings, dapsDriver, connectionFuture); tlsClient.connect(settings.getHost(), settings.getServerPort()); } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) { - throw new Idscp2Exception("Call to connect() has failed", e); + connectionFuture.completeExceptionally(new Idscp2Exception("Call to connect() has failed", e)); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 01616a4e1..cfdf24e59 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -3,9 +3,10 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.keystores.PreConfiguration; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSConstants; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.TLSSessionVerificationHelper; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelEndpoint; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannelListener; @@ -22,7 +23,7 @@ import java.util.concurrent.CompletableFuture; /** - * A TLS Client that notifies an Idscp2Configuration when a secure channel was created and the + * A TLS Client that notifies an Idscp2ServerFactory when a secure channel was created and the * TLS handshake is done. The client is notified from an InputListenerThread when new data are * available and transfer it to the SecureChannelListener * @@ -36,11 +37,17 @@ public class TLSClient implements HandshakeCompletedListener, DataAvailableListe private DataOutputStream out; private InputListenerThread inputListenerThread; private final CompletableFuture listenerPromise = new CompletableFuture<>(); - private final SecureChannelInitListener secureChannelInitListener; + private final Idscp2Settings clientSettings; + private final DapsDriver dapsDriver; + private final CompletableFuture connectionFuture; - public TLSClient(Idscp2Settings clientSettings, SecureChannelInitListener secureChannelInitListener) + public TLSClient(Idscp2Settings clientSettings, + DapsDriver dapsDriver, + CompletableFuture connectionFuture) throws IOException, KeyManagementException, NoSuchAlgorithmException { - this.secureChannelInitListener = secureChannelInitListener; + this.clientSettings = clientSettings; + this.dapsDriver = dapsDriver; + this.connectionFuture = connectionFuture; // init TLS Client @@ -92,8 +99,7 @@ public void connect(String hostname, int port) { } try { - sslSocket.connect(new InetSocketAddress(hostname, - port)); + sslSocket.connect(new InetSocketAddress(hostname, port)); LOG.debug("Client is connected to server {}:{}", hostname, port); //set clientSocket timeout to allow safeStop() @@ -105,7 +111,6 @@ public void connect(String hostname, int port) { inputListenerThread = new InputListenerThread(clientSocket.getInputStream()); inputListenerThread.register(this); - //start tls handshake sslSocket.addHandshakeCompletedListener(this); LOG.debug("Start TLS Handshake"); sslSocket.startHandshake(); @@ -119,7 +124,7 @@ public void connect(String hostname, int port) { } private void disconnect() { - LOG.debug("Disconnecting from tls server"); + LOG.debug("Disconnecting from TLS server..."); //close listener if (inputListenerThread != null && inputListenerThread.isAlive()) { inputListenerThread.safeStop(); @@ -129,7 +134,7 @@ private void disconnect() { try { clientSocket.close(); } catch (IOException e) { - //nothing to do + onError(e); } } } @@ -141,7 +146,7 @@ public void onClose() { @Override public void onError(Throwable t) { - listenerPromise.thenAccept(secureChannelListener -> secureChannelListener.onError(t)); + listenerPromise.thenAccept(listener -> listener.onError(t)); } @Override @@ -185,14 +190,15 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) LOG.debug("TLS session is valid"); } catch (SSLPeerUnverifiedException e) { disconnect(); - throw new Idscp2Exception("TLS session is not valid. Close TLS connection", e); + connectionFuture.completeExceptionally( + new Idscp2Exception("TLS session is not valid. Close TLS connection", e)); } // Create secure channel, register secure channel as message listener and notify IDSCP2 Configuration. SecureChannel secureChannel = new SecureChannel(this); this.listenerPromise.complete(secureChannel); + this.connectionFuture.complete(new Idscp2Connection(secureChannel, clientSettings, dapsDriver)); inputListenerThread.start(); - secureChannelInitListener.onSecureChannel(secureChannel, null); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java index ac954f550..d6af0fc05 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/interfaces/SecureChannelDriver.java @@ -1,5 +1,6 @@ package de.fhg.aisec.ids.idscp2.drivers.interfaces; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.SecureChannelInitListener; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; @@ -17,7 +18,7 @@ public interface SecureChannelDriver { /* * Asynchronous method to create a secure connection to a secure server */ - void connect(Idscp2Settings settings, SecureChannelInitListener channelInitListener); + void connect(Idscp2Settings settings, DapsDriver dapsDriver, CompletableFuture connectionFuture); /* * Starting a secure server diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java index 07b580f40..109444db7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ClientInitiator.java @@ -1,6 +1,5 @@ package de.fhg.aisec.ids.idscp2.example; -import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy; @@ -10,11 +9,10 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifier; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dVerifierConfig; import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver; -import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2ClientFactory; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry; @@ -24,9 +22,11 @@ import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; -public class Idscp2ClientInitiator implements Idscp2EndpointListener { +public class Idscp2ClientInitiator { private static final Logger LOG = LoggerFactory.getLogger(Idscp2ClientInitiator.class); + private final CompletableFuture connectionFuture = new CompletableFuture<>(); + public void init(Idscp2Settings settings) { SecureChannelDriver secureChannelDriver = new NativeTLSDriver(); @@ -41,8 +41,6 @@ public void init(Idscp2Settings settings) { .setDapsUrl("https://daps.aisec.fraunhofer.de") .build(); - DapsDriver dapsDriver = new DefaultDapsDriver(config); - RatProverDriverRegistry.getInstance().registerDriver( "Dummy", RatProverDummy.class, null); RatVerifierDriverRegistry.getInstance().registerDriver( @@ -57,42 +55,37 @@ public void init(Idscp2Settings settings) { new TPM2dVerifierConfig.Builder().build() ); - Idscp2Configuration clientConfig = new Idscp2Configuration( - this, - settings, - dapsDriver, + final var clientConfig = new Idscp2ClientFactory( + new DefaultDapsDriver(config), secureChannelDriver ); - clientConfig.connect(settings); - } - - @Override - public void onConnection(Idscp2Connection connection) { - System.out.println("Client: New connection with id " + connection.getId()); - connection.addConnectionListener(new Idscp2ConnectionAdapter() { - @Override - public void onError(Throwable t) { - LOG.error("Client connection error occurred", t); - } + clientConfig.connect(settings, connectionFuture); + connectionFuture.thenAccept(connection -> { + System.out.println("Client: New connection with id " + connection.getId()); + connection.addConnectionListener(new Idscp2ConnectionAdapter() { + @Override + public void onError(Throwable t) { + LOG.error("Client connection error occurred", t); + } - @Override - public void onClose(Idscp2Connection connection) { - LOG.info("Client: Connection with id " + connection.getId() + " has been closed"); - } + @Override + public void onClose(Idscp2Connection connection) { + LOG.info("Client: Connection with id " + connection.getId() + " has been closed"); + } + }); + connection.addGenericMessageListener(((c, type, data) -> System.out.println( + "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); + connection.addMessageListener("ping", (c, type, data) -> { + System.out.println("Received ping message: " + new String(data, StandardCharsets.UTF_8)); + CompletableFuture.runAsync(c::close); // FSM error if run from the same thread + }); + connection.unlockMessaging(); + System.out.println("Sending PING..."); + connection.send("ping", "PING".getBytes(StandardCharsets.UTF_8)); + }).exceptionally(t -> { + LOG.error("Client endpoint error occurred", t); + return null; }); - connection.addGenericMessageListener(((c, type, data) -> System.out.println( - "Received message of type \"" + type + "\":\n" + new String(data, StandardCharsets.UTF_8)))); - connection.addMessageListener("ping", (c, type, data) -> { - System.out.println("Received ping message: " + new String(data, StandardCharsets.UTF_8)); - CompletableFuture.runAsync(c::close); // FSM error if run from the same thread - }); - System.out.println("Sending PING..."); - connection.send("ping", "PING".getBytes(StandardCharsets.UTF_8)); - } - - @Override - public void onError(Throwable t) { - LOG.error("Client endpoint error occurred", t); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index 960a477f6..5ad62b29e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -14,7 +14,7 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2ServerFactory; import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; @@ -57,7 +57,7 @@ public void init(Idscp2Settings settings) { new TPM2dVerifierConfig.Builder().build() ); - Idscp2Configuration serverConfig = new Idscp2Configuration( + Idscp2ServerFactory serverConfig = new Idscp2ServerFactory( this, settings, dapsDriver, @@ -66,12 +66,12 @@ public void init(Idscp2Settings settings) { Idscp2Server idscp2Server = serverConfig.listen(settings); - try { - Thread.sleep(40_000); //run server for 2 minutes - } catch (Exception ignored) { - } finally { - idscp2Server.terminate(); - } +// try { +// Thread.sleep(40_000); //run server for 2 minutes +// } catch (Exception ignored) { +// } finally { +// idscp2Server.terminate(); +// } } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index 74dc49f6b..e8860d1a4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -1,11 +1,15 @@ package de.fhg.aisec.ids.idscp2.idscp_core; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings; import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; +import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; +import java.util.concurrent.CompletableFuture; /** * The IDSCP2 Connection class holds connections between connectors @@ -23,9 +27,19 @@ public class Idscp2Connection { private final Map> messageListeners = new HashMap<>(); private final FastLatch messageLatch = new FastLatch(); - public Idscp2Connection(FSM fsm, String connectionId) { - this.fsm = fsm; - this.connectionId = connectionId; + public Idscp2Connection(SecureChannel secureChannel, Idscp2Settings settings, DapsDriver dapsDriver) { + this.connectionId = UUID.randomUUID().toString(); + fsm = new FSM( + this, + secureChannel, + dapsDriver, + settings.getSupportedAttestation().getRatMechanisms(), + settings.getExpectedAttestation().getRatMechanisms(), + settings.getRatTimeoutDelay()); + secureChannel.setFsm(fsm); + LOG.debug("A new IDSCP2 connection with id {} was created, starting handshake...", connectionId); + // Schedule IDSCP handshake asynchronously + CompletableFuture.runAsync(fsm::startIdscpHandshake); } public void unlockMessaging() { @@ -36,11 +50,13 @@ public void unlockMessaging() { * Close the idscp connection */ public void close() { - // Unregister connection from the server + LOG.debug("Closing connection {}...", connectionId); + // If server connection, this also unregisters the connection from the server. if (fsm.isNotClosed()) { connectionListeners.forEach(l -> l.onClose(this)); } fsm.terminate(); + LOG.debug("IDSCP2 connection {} closed", connectionId); } /** diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ClientFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ClientFactory.java new file mode 100644 index 000000000..fad670b6c --- /dev/null +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ClientFactory.java @@ -0,0 +1,37 @@ +package de.fhg.aisec.ids.idscp2.idscp_core.configuration; + +import de.fhg.aisec.ids.idscp2.drivers.interfaces.DapsDriver; +import de.fhg.aisec.ids.idscp2.drivers.interfaces.SecureChannelDriver; +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.CompletableFuture; + +/** + * Idscp2ServerFactory class, provides IDSCP2 API to the User (Idscp2EndpointListener) + * + * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) + */ +public class Idscp2ClientFactory { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ClientFactory.class); + + private final DapsDriver dapsDriver; + private final SecureChannelDriver secureChannelDriver; + + public Idscp2ClientFactory(DapsDriver dapsDriver, + SecureChannelDriver secureChannelDriver + ) { + this.dapsDriver = dapsDriver; + this.secureChannelDriver = secureChannelDriver; + } + + /** + * User API to create a IDSCP2 connection as a client + */ + public void connect(Idscp2Settings settings, CompletableFuture connectionFuture) { + LOG.info("Connect to an IDSCP2 server ({})", settings.getHost()); + secureChannelDriver.connect(settings, dapsDriver, connectionFuture); + } + +} diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java similarity index 65% rename from idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java rename to idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java index 57d871d1b..9de609093 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Configuration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java @@ -6,30 +6,28 @@ import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionAdapter; -import de.fhg.aisec.ids.idscp2.idscp_core.finite_state_machine.FSM; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server; import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.ServerConnectionListener; import de.fhg.aisec.ids.idscp2.idscp_core.secure_channel.SecureChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.UUID; import java.util.concurrent.CompletableFuture; /** - * Idscp2Configuration class, provides IDSCP2 API to the User (Idscp2EndpointListener) + * Idscp2ServerFactory class, provides IDSCP2 API to the User (Idscp2EndpointListener) * * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ -public class Idscp2Configuration implements SecureChannelInitListener { - private static final Logger LOG = LoggerFactory.getLogger(Idscp2Configuration.class); +public class Idscp2ServerFactory implements SecureChannelInitListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ServerFactory.class); private final Idscp2EndpointListener endpointListener; private final Idscp2Settings settings; private final DapsDriver dapsDriver; private final SecureChannelDriver secureChannelDriver; - public Idscp2Configuration(Idscp2EndpointListener endpointListener, + public Idscp2ServerFactory(Idscp2EndpointListener endpointListener, Idscp2Settings settings, DapsDriver dapsDriver, SecureChannelDriver secureChannelDriver @@ -40,14 +38,6 @@ public Idscp2Configuration(Idscp2EndpointListener endpointListener, this.secureChannelDriver = secureChannelDriver; } - /** - * User API to create a IDSCP2 connection as a client - */ - public void connect(Idscp2Settings settings) { - LOG.info("Connect to an IDSCP2 server ({})", settings.getHost()); - secureChannelDriver.connect(settings, this); - } - /* * User API to create a new IDSCP2 Server that starts a Secure Server that listens to new * secure channels @@ -76,32 +66,18 @@ public Idscp2Server listen(Idscp2Settings settings) throws Idscp2Exception { public synchronized void onSecureChannel(SecureChannel secureChannel, CompletableFuture serverListenerPromise) { LOG.trace("A new secure channel for an IDSCP2 connection was established"); - FSM fsm = new FSM( - secureChannel, - dapsDriver, - settings.getSupportedAttestation().getRatMechanisms(), - settings.getExpectedAttestation().getRatMechanisms(), - settings.getRatTimeoutDelay()); - - fsm.startIdscpHandshake(); - - String connectionId = UUID.randomUUID().toString(); // Threads calling onMessage() will be blocked until all listeners have been registered, see below - Idscp2Connection newConnection = new Idscp2Connection(fsm, connectionId); - fsm.registerConnection(newConnection); - LOG.debug("A new IDSCP2 connection with id {} was created", connectionId); - if (serverListenerPromise != null) { - // Complete the connection promise for the IDSCP server - serverListenerPromise.thenAccept(serverListener -> { - serverListener.onConnectionCreated(newConnection); - newConnection.addConnectionListener(new Idscp2ConnectionAdapter() { - @Override - public void onClose(Idscp2Connection connection) { - serverListener.onConnectionClose(connection); - } - }); + Idscp2Connection newConnection = new Idscp2Connection(secureChannel, settings, dapsDriver); + // Complete the connection promise for the IDSCP server + serverListenerPromise.thenAccept(serverListener -> { + serverListener.onConnectionCreated(newConnection); + newConnection.addConnectionListener(new Idscp2ConnectionAdapter() { + @Override + public void onClose(Idscp2Connection connection) { + serverListener.onConnectionClose(connection); + } }); - } + }); endpointListener.onConnection(newConnection); newConnection.unlockMessaging(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java index 6c22dda3f..8fdf3cc8b 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java @@ -11,7 +11,7 @@ * @author Leon Beckmann (leon.beckmann@aisec.fraunhofer.de) */ public class Idscp2Settings { - public static final int DEFAULT_SERVER_PORT = 8080; + public static final int DEFAULT_SERVER_PORT = 29292; private int serverPort = DEFAULT_SERVER_PORT; private String host = "localhost"; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 07a7158cd..8df2dcd40 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -5,7 +5,6 @@ import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatProverDriver; import de.fhg.aisec.ids.idscp2.drivers.interfaces.RatVerifierDriver; import de.fhg.aisec.ids.idscp2.error.Idscp2Exception; -import de.fhg.aisec.ids.idscp2.idscp_core.FastLatch; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection; import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageHelper; import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatProverDriverRegistry; @@ -49,7 +48,9 @@ enum FSM_STATE { private State currentState; /* ---------------- end of states --------------- */ - private final SecureChannel secureChannel; //secure underlying channel + + private final Idscp2Connection connection; + private final SecureChannel secureChannel; private RatProverDriver ratProverDriver; private RatVerifierDriver ratVerifierDriver; @@ -69,14 +70,6 @@ enum FSM_STATE { private String proverMechanism = null; //RAT prover mechanism private String verifierMechanism = null; //RAT Verifier mechanism - /* - * The idscp message listener, that should receive the IDSCP2 messages from the fsm - * And a listener latch to ensure that the listener is available and the message does not get - * lost - */ - private Idscp2Connection connection; - private final FastLatch connectionLatch = new FastLatch(); - /* * A FIFO-fair synchronization lock for the finite state machine */ @@ -98,7 +91,7 @@ enum FSM_STATE { /* * Check if FSM is closed forever */ - private boolean fsmIsClosed = false; + private boolean fsmTerminated = false; /* ---------------------- Timer ---------------------- */ private final Timer datTimer; @@ -108,7 +101,7 @@ enum FSM_STATE { private final Timer verifierHandshakeTimer; /* ---------------- end of Timer --------------- */ - public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, + public FSM(Idscp2Connection connection, SecureChannel secureChannel, DapsDriver dapsDriver, String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout) { @@ -172,12 +165,11 @@ public FSM(SecureChannel secureChannel, DapsDriver dapsDriver, ratTimer, handshakeTimer)); - //set initial state + // Set initial state currentState = states.get(FSM_STATE.STATE_CLOSED); - //register fsm to the secure channel for bi-directional communication between fsm and sc + this.connection = connection; this.secureChannel = secureChannel; - secureChannel.setFsm(this); } private void checkForFsmCircles() { @@ -237,7 +229,7 @@ public void onMessage(byte[] data) { try { while (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { - if (fsmIsClosed) { + if (fsmTerminated) { return; } @@ -366,11 +358,8 @@ public void terminate() { //check for incorrect usage checkForFsmCircles(); - LOG.debug("Close IDSCP2 connection"); + LOG.debug("Sending stop message to connection peer..."); onControlMessage(InternalControlMessage.IDSCP_STOP); - LOG.trace("Close secure channel"); - secureChannel.close(); - LOG.debug("IDSCP2 connection closed"); } /* @@ -380,26 +369,25 @@ public void terminate() { * driver implementations */ public void startIdscpHandshake() throws Idscp2Exception { - //check for incorrect usage checkForFsmCircles(); fsmIsBusy.lock(); try { if (currentState.equals(states.get(FSM_STATE.STATE_CLOSED))) { - if (fsmIsClosed) { + if (fsmTerminated) { throw new Idscp2Exception("FSM is in a final closed state forever"); } - //trigger handshake init + // trigger handshake init onControlMessage(InternalControlMessage.START_IDSCP_HANDSHAKE); - //wait until handshake was successful or failed + // wait until handshake was successful or failed while (!handshakeResultAvailable) { idscpHandshakeLock.await(); } - if (!isConnected()) { + if (!isConnected() && !fsmTerminated) { //handshake failed, throw exception throw new Idscp2Exception("Handshake failed"); } @@ -433,7 +421,7 @@ public void onError(Throwable t) { // Broadcast the error to the respective listeners connection.onError(t); - //check for incorrect usage + // Check for incorrect usage checkForFsmCircles(); onControlMessage(InternalControlMessage.ERROR); @@ -447,11 +435,10 @@ public void onError(Throwable t) { */ @Override public void onClose() { - - //check for incorrect usage + // Check for incorrect usage checkForFsmCircles(); - onControlMessage(InternalControlMessage.ERROR); + onControlMessage(InternalControlMessage.IDSCP_STOP); } /* @@ -482,14 +469,6 @@ public boolean isConnected() { return currentState.equals(states.get(FSM_STATE.STATE_ESTABLISHED)); } - /* - * Register an IDSCP2 message listener - */ - public void registerConnection(Idscp2Connection connection) { - this.connection = connection; - connectionLatch.unlock(); - } - /* * Notify handshake lock about result */ @@ -598,21 +577,35 @@ void stopRatProverDriver() { * and notify User or handshake lock about closure */ void shutdownFsm() { + LOG.debug("Shutting down FSM of connection {}...", connection.getId()); + + if (LOG.isTraceEnabled()) { + LOG.trace("Closing secure channel of connection {}...", connection.getId()); + } secureChannel.close(); + if (LOG.isTraceEnabled()) { + LOG.trace("Clearing timeouts..."); + } datTimer.cancelTimeout(); ratTimer.cancelTimeout(); handshakeTimer.cancelTimeout(); + if (LOG.isTraceEnabled()) { + LOG.trace("Stopping RAT components..."); + } // Cancels proverHandshakeTimer this.stopRatProverDriver(); // Cancels verifierHandshakeTimer this.stopRatVerifierDriver(); - fsmIsClosed = true; + if (LOG.isTraceEnabled()) { + LOG.trace("Mark FSM as terminated..."); + } + fsmTerminated = true; // Notify upper layer via handshake or closeListener - if (handshakeResultAvailable) { - connectionLatch.await(); - connection.onClose(); - } else { + if (!handshakeResultAvailable) { + if (LOG.isTraceEnabled()) { + LOG.trace("Notify handshake lock..."); + } notifyHandshakeCompleteLock(); } } @@ -621,7 +614,6 @@ void shutdownFsm() { * Provide IDSCP2 message to the message listener */ void notifyIdscpMsgListener(String type, byte[] data) { - this.connectionLatch.await(); this.connection.onMessage(type, data); LOG.debug("Idscp data has been passed to connection listener"); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java index b6acac5b5..f445fbab6 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateClosed.java @@ -62,15 +62,27 @@ public StateClosed(FSM fsm, } )); + // This origins from onClose(), so just ignore it + this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( + event -> { + if (LOG.isTraceEnabled()) { + LOG.trace("Received STOP in STATE_CLOSED, ignored."); + } + return this; + } + )); + this.setNoTransitionHandler( event -> { - LOG.debug("No transition available for given event {}, stack trace for analysis:\n{}", - event, - Arrays.stream(Thread.currentThread().getStackTrace()) - .skip(1) - .map(Object::toString) - .collect(Collectors.joining("\n"))); - LOG.debug("Stay in state STATE_CLOSED"); + if (LOG.isDebugEnabled()) { + LOG.debug("No transition available for given event {}, stack trace for analysis:\n{}", + event, + Arrays.stream(Thread.currentThread().getStackTrace()) + .skip(1) + .map(Object::toString) + .collect(Collectors.joining("\n"))); + LOG.debug("Stay in state STATE_CLOSED"); + } return this; } ); @@ -86,7 +98,6 @@ private void runExitCode(Condition onMessageLock) { void runEntryCode(FSM fsm) { //State Closed entry code LOG.debug("Switched to state STATE_CLOSED"); - LOG.debug("Terminate and free all resources and lock fsm forever"); fsm.shutdownFsm(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java index db821241b..d4f3edb9a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForHello.java @@ -52,7 +52,7 @@ public StateWaitForHello(FSM fsm, this.addTransition(InternalControlMessage.IDSCP_STOP.getValue(), new Transition( event -> { - LOG.debug("Received stop signal from user. Send IDSC_CLOSE"); + LOG.debug("Received stop signal from user. Send IDSCP_CLOSE"); fsm.sendFromFSM(Idscp2MessageHelper.createIdscpCloseMessage("User close", IDSCP2.IdscpClose.CloseCause.USER_SHUTDOWN)); return fsm.getState(FSM.FSM_STATE.STATE_CLOSED); From dd976bc7c6efbf7c3cbbede0ed1717926b00f4d8 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 01:21:56 +0200 Subject: [PATCH 088/237] Fixed client producer (send only), added untested client consumer --- .../idscp2/client/Idscp2ClientConsumer.kt | 24 ++++++-- .../idscp2/client/Idscp2ClientEndpoint.kt | 55 +++---------------- .../idscp2/client/Idscp2ClientProducer.kt | 28 +++++++++- .../camel/idscp2/server/CamelIdscp2Server.kt | 10 ++-- .../idscp2/server/Idscp2ServerConsumer.kt | 4 +- .../idscp2/server/Idscp2ServerEndpoint.kt | 4 +- 6 files changed, 64 insertions(+), 61 deletions(-) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt index 13d6a27e4..563df78cf 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt @@ -21,20 +21,30 @@ import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener import org.apache.camel.Processor import org.apache.camel.support.DefaultConsumer import org.slf4j.LoggerFactory +import java.util.concurrent.CompletableFuture /** * The IDSCP2 server consumer. */ class Idscp2ClientConsumer(private val endpoint: Idscp2ClientEndpoint, processor: Processor) : DefaultConsumer(endpoint, processor), Idscp2MessageListener { + private val connectionFuture = CompletableFuture() + override fun doStart() { super.doStart() - endpoint.addConsumer(this) + endpoint.makeConnection(connectionFuture) + connectionFuture.thenAccept { it.addGenericMessageListener(this) } } - override fun doStop() { - endpoint.removeConsumer(this) - super.doStop() + public override fun doStop() { + if (connectionFuture.isDone) { + val connection = connectionFuture.get() + LOG.debug("Stopping IDSCP2 client connection {}...", connection.id) + connection.close() + } else { + LOG.debug("Canceling IDSCP2 client connection...") + connectionFuture.cancel(true) + } } override fun onMessage(connection: Idscp2Connection, type: String, data: ByteArray) { @@ -49,9 +59,11 @@ class Idscp2ClientConsumer(private val endpoint: Idscp2ClientEndpoint, processor // Handle response val response = exchange.message val responseType = response.getHeader("idscp2.type", String::class.java) - connection.send(responseType, response.getBody(ByteArray::class.java)) + if (response.body != null && responseType != null) { + connection.send(responseType, response.getBody(ByteArray::class.java)) + } } catch (e: Exception) { - LOG.error("Error in Idscp2ServerConsumer.onMessage()", e) + LOG.error("Error in Idscp2ClientConsumer.onMessage()", e) } finally { doneUoW(exchange) } diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt index 52a4ec275..3f923369e 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt @@ -18,19 +18,18 @@ package de.fhg.aisec.ids.camel.idscp2.client import de.fhg.aisec.ids.api.settings.Settings import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent -import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2ClientFactory import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings import org.apache.camel.Processor import org.apache.camel.Producer import org.apache.camel.spi.UriEndpoint import org.apache.camel.support.DefaultEndpoint import org.slf4j.LoggerFactory -import java.util.* +import java.util.concurrent.CompletableFuture import java.util.regex.Pattern @UriEndpoint( @@ -40,11 +39,9 @@ import java.util.regex.Pattern label = "ids" ) class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2ClientComponent?) : - DefaultEndpoint(uri, component), Idscp2EndpointListener { - private val clientConfiguration: Idscp2Configuration + DefaultEndpoint(uri, component) { + private val dapsDriverConfig: DefaultDapsDriverConfig private val clientSettings: Idscp2Settings - private var connection: Idscp2Connection? = null - private val consumers: MutableSet = HashSet() init { val settings: Settings = Idscp2OsgiComponent.getSettings() @@ -62,8 +59,8 @@ class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2Cli .setDapsKeyAlias("1") .setRatTimeoutDelay(300) .build() - val config = DefaultDapsDriverConfig.Builder() - .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + dapsDriverConfig = DefaultDapsDriverConfig.Builder() + .setConnectorUUID(settings.connectorConfig.connectorUUID) .setKeyStorePath(clientSettings.keyStorePath) .setTrustStorePath(clientSettings.trustStorePath) .setKeyStorePassword(clientSettings.keyStorePassword) @@ -71,61 +68,27 @@ class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2Cli .setKeyAlias(clientSettings.dapsKeyAlias) .setDapsUrl(settings.connectorConfig.dapsUrl) .build() - clientConfiguration = Idscp2Configuration( - this, - clientSettings, - DefaultDapsDriver(config), - NativeTLSDriver() - ) } - @Synchronized - fun addConsumer(consumer: Idscp2ClientConsumer) { - consumers.add(consumer) - connection?.addGenericMessageListener(consumer) + fun makeConnection(connectionFuture: CompletableFuture) { + return Idscp2ClientFactory(DefaultDapsDriver(dapsDriverConfig), NativeTLSDriver()) + .connect(clientSettings, connectionFuture) } - @Synchronized - fun removeConsumer(consumer: Idscp2ClientConsumer) { - consumers.remove(consumer) - connection?.removeGenericMessageListener(consumer) - } - - @Synchronized - fun sendMessage(type: String, body: ByteArray) { - connection?.send(type, body) - } - - @Synchronized override fun createProducer(): Producer { return Idscp2ClientProducer(this) } - @Synchronized override fun createConsumer(processor: Processor): org.apache.camel.Consumer { return Idscp2ClientConsumer(this, processor) } - @Synchronized - override fun onConnection(connection: Idscp2Connection) { - LOG.debug("New IDSCP2 connection on $endpointUri, register consumer listeners") - consumers.forEach { connection.addGenericMessageListener(it) } - } - - override fun onError(error: String) { - LOG.error("Error in IDSCP2 client endpoint $endpointUri:\n$error") - } - - @Synchronized public override fun doStart() { LOG.debug("Starting IDSCP2 client endpoint $endpointUri") - clientConfiguration.connect(clientSettings) } - @Synchronized public override fun doStop() { LOG.debug("Stopping IDSCP2 client endpoint $endpointUri") - connection?.close() } companion object { diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt index 380ae3f28..a8755252a 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt @@ -16,20 +16,46 @@ */ package de.fhg.aisec.ids.camel.idscp2.client +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection import org.apache.camel.Exchange import org.apache.camel.support.DefaultProducer +import org.slf4j.LoggerFactory +import java.util.concurrent.CompletableFuture /** * The IDSCP2 server producer. * Sends each message to all clients connected to this server endpoint. */ class Idscp2ClientProducer(private val endpoint: Idscp2ClientEndpoint) : DefaultProducer(endpoint) { + private val connectionFuture = CompletableFuture() override fun process(exchange: Exchange) { val message = exchange.getIn() val type = message.getHeader("idscp2.type", String::class.java) val body = message.getBody(ByteArray::class.java) - endpoint.sendMessage(type, body) + connectionFuture.get().let { + it.unlockMessaging() + it.send(type, body) + } } + override fun doStart() { + super.doStart() + endpoint.makeConnection(connectionFuture) + } + + public override fun doStop() { + if (connectionFuture.isDone) { + val connection = connectionFuture.get() + LOG.debug("Stopping IDSCP2 client connection {}...", connection.id) + connection.close() + } else { + LOG.debug("Canceling IDSCP2 client connection...") + connectionFuture.cancel(true) + } + } + + companion object { + private val LOG = LoggerFactory.getLogger(Idscp2ClientProducer::class.java) + } } \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt index f531083ff..5a84164a4 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt @@ -6,7 +6,7 @@ import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDrive import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection -import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Configuration +import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2ServerFactory import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings import de.fhg.aisec.ids.idscp2.idscp_core.idscp_server.Idscp2Server import java.util.* @@ -17,7 +17,7 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener init { val dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID("edc5d7b3-a398-48f0-abb0-3751530c4fed") + .setConnectorUUID(Idscp2OsgiComponent.getSettings().connectorConfig.connectorUUID) .setKeyStorePath(serverSettings.keyStorePath) .setTrustStorePath(serverSettings.trustStorePath) .setKeyStorePassword(serverSettings.keyStorePassword) @@ -25,7 +25,7 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener .setKeyAlias(serverSettings.dapsKeyAlias) .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) .build() - val serverConfiguration = Idscp2Configuration( + val serverConfiguration = Idscp2ServerFactory( this, serverSettings, DefaultDapsDriver(dapsDriverConfig), @@ -38,8 +38,8 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener listeners.forEach { it.onConnection(connection) } } - override fun onError(error: String) { - listeners.forEach { it.onError(error) } + override fun onError(t: Throwable) { + listeners.forEach { it.onError(t) } } val allConnections: Set = server.allConnections diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt index 6b053557d..04ec67ee5 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerConsumer.kt @@ -49,7 +49,9 @@ class Idscp2ServerConsumer(private val endpoint: Idscp2ServerEndpoint, processor // Handle response val response = exchange.message val responseType = response.getHeader("idscp2.type", String::class.java) - connection.send(responseType, response.getBody(ByteArray::class.java)) + if (response.body != null && responseType != null) { + connection.send(responseType, response.getBody(ByteArray::class.java)) + } } catch (e: Exception) { LOG.error("Error in Idscp2ServerConsumer.onMessage()", e) } finally { diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt index b75b13056..3c1f87f95 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt @@ -89,8 +89,8 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser consumers.forEach { connection.addGenericMessageListener(it) } } - override fun onError(error: String) { - LOG.error("Error in IDSCP2 server endpoint $endpointUri:\n$error") + override fun onError(t: Throwable) { + LOG.error("Error in IDSCP2 server endpoint $endpointUri", t) } @Synchronized From 4601b3a6beea27d9d2a0c771501c79f2a87fa28a Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 16:42:53 +0200 Subject: [PATCH 089/237] Added keyPassword parameter, changed timeout from int to long --- .../keystores/PreConfiguration.java | 3 ++- .../secure_channel/client/TLSClient.java | 1 + .../secure_channel/server/TLSServer.java | 1 + .../configuration/Idscp2Settings.java | 17 ++++++++++++++--- .../idscp_core/finite_state_machine/FSM.java | 2 +- .../finite_state_machine/StateWaitForRat.java | 2 +- .../StateWaitForRatVerifier.java | 2 +- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java index e12a2c38d..5c334dadc 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/PreConfiguration.java @@ -62,6 +62,7 @@ public static TrustManager[] getX509ExtTrustManager( * throws RuntimeException of creating KeyManager fails */ public static KeyManager[] getX509ExtKeyManager( + String keyPassword, String keyStorePath, String keyStorePassword, String certAlias, @@ -76,7 +77,7 @@ public static KeyManager[] getX509ExtKeyManager( keystore.load(jksKeyStoreIn, keyStorePassword.toCharArray()); final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX"); //PKIX from SunJSSE - keyManagerFactory.init(keystore, keyStorePassword.toCharArray()); + keyManagerFactory.init(keystore, keyPassword.toCharArray()); myKeyManager = keyManagerFactory.getKeyManagers(); /* set up keyManager config */ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index cfdf24e59..03065d17f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -61,6 +61,7 @@ public TLSClient(Idscp2Settings clientSettings, // get array of KeyManagers, that contains only one instance of X509ExtendedKeyManager, which enables // connection specific key selection via key alias KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( + clientSettings.getKeyPassword(), clientSettings.getKeyStorePath(), clientSettings.getKeyStorePassword(), clientSettings.getCertificateAlias(), diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java index f172c53da..d2e48e7a4 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/server/TLSServer.java @@ -53,6 +53,7 @@ public TLSServer(Idscp2Settings serverSettings, SecureChannelInitListener secure // which enables connection specific key selection via key alias LOG.debug("Creating key manager for TLS server..."); KeyManager[] myKeyManager = PreConfiguration.getX509ExtKeyManager( + serverSettings.getKeyPassword(), serverSettings.getKeyStorePath(), serverSettings.getKeyStorePassword(), serverSettings.getCertificateAlias(), diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java index 8fdf3cc8b..974e5b074 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2Settings.java @@ -12,11 +12,13 @@ */ public class Idscp2Settings { public static final int DEFAULT_SERVER_PORT = 29292; + public static final String DEFAULT_RAT_TIMEOUT_DELAY = "600"; private int serverPort = DEFAULT_SERVER_PORT; private String host = "localhost"; private String trustStorePath = null; private String trustStorePassword = "password"; + private String keyPassword = "password"; private String keyStorePath = null; private String keyStorePassword = "password"; private String certificateAlias = "1.0.1"; @@ -24,7 +26,7 @@ public class Idscp2Settings { private String keyStoreKeyType = "RSA"; private AttestationConfig supportedAttestation = new AttestationConfig(); private AttestationConfig expectedAttestation = new AttestationConfig(); - private int ratTimeoutDelay = 20; + private long ratTimeoutDelay = Integer.parseInt(DEFAULT_RAT_TIMEOUT_DELAY); @SuppressWarnings("unused") public static class Builder { @@ -43,6 +45,11 @@ public Builder setServerPort(int serverPort) { return this; } + public Builder setKeyPassword(String pwd) { + this.settings.keyPassword = pwd; + return this; + } + @NonNull public Builder setTrustStorePath(String path) { this.settings.trustStorePath = path; @@ -97,7 +104,7 @@ public Builder setExpectedAttestation(AttestationConfig suite) { return this; } - public Builder setRatTimeoutDelay(int delay) { + public Builder setRatTimeoutDelay(long delay) { this.settings.ratTimeoutDelay = delay; return this; } @@ -125,6 +132,10 @@ public String getTrustStorePassword() { return trustStorePassword; } + public String getKeyPassword() { + return keyPassword; + } + public String getKeyStorePath() { return keyStorePath; } @@ -153,7 +164,7 @@ public AttestationConfig getExpectedAttestation() { return expectedAttestation; } - public int getRatTimeoutDelay() { + public long getRatTimeoutDelay() { return ratTimeoutDelay; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 8df2dcd40..21ddf8a68 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -102,7 +102,7 @@ enum FSM_STATE { /* ---------------- end of Timer --------------- */ public FSM(Idscp2Connection connection, SecureChannel secureChannel, DapsDriver dapsDriver, - String[] localSupportedRatSuite, String[] localExpectedRatSuite, int ratTimeout) { + String[] localSupportedRatSuite, String[] localExpectedRatSuite, long ratTimeout) { /* ------------- Timeout Handler Routines ------------*/ diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java index 5aa079906..14f59d985 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRat.java @@ -22,7 +22,7 @@ public StateWaitForRat(FSM fsm, Timer verifierHandshakeTimer, Timer proverHandshakeTimer, Timer ratTimer, - int ratTimerDelay, + long ratTimerDelay, DapsDriver dapsDriver) { diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java index 211082e3d..e0a3d5460 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/StateWaitForRatVerifier.java @@ -21,7 +21,7 @@ public StateWaitForRatVerifier(FSM fsm, Timer ratTimer, Timer handshakeTimer, Timer verifierHandshakeTimer, - int ratTimeoutDelay) { + long ratTimeoutDelay) { /*--------------------------------------------------- * STATE_WAIT_FOR_RAT_VERIFIER - Transition Description From c9ec3108ff21321e4ecfbdeffea145267f4603e9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 17:07:38 +0200 Subject: [PATCH 090/237] Typo fix for server producer --- .../fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt index 691a0f4b9..f48147343 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerProducer.kt @@ -27,7 +27,7 @@ class Idscp2ServerProducer(private val endpoint: Idscp2ServerEndpoint) : Default override fun process(exchange: Exchange) { val message = exchange.getIn() - val type = message.getHeader("idscp.type", String::class.java) + val type = message.getHeader("idscp2.type", String::class.java) val body = message.getBody(ByteArray::class.java) endpoint.sendMessage(type, body) } From a84291f0fcf28261f733c79527b28d91bfb1bac1 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Wed, 27 May 2020 18:57:08 +0200 Subject: [PATCH 091/237] Reduced key manager log verbosity --- .../CustomX509ExtendedKeyManager.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index 8d109d4d1..06173e5f7 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -88,13 +88,12 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock return this.certAlias; } else { LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); - return null; } - } else { - LOG.warn("Invalid keyType '{}' in chooseServerAlias() in class X509ExtendedKeyManager", keyType); - LOG.warn("Expected: '{}'", this.keyType); - return null; + } else if (LOG.isDebugEnabled()) { + LOG.debug("Different keyType '{}' in chooseServerAlias() in CustomX509ExtendedKeyManager, expected '{}'", + keyType, this.keyType); } + return null; } @Override @@ -102,12 +101,10 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock called by client and server in TLS Handshake after alias was chosen */ public X509Certificate[] getCertificateChain(String certAlias) { if (certAlias.equals(this.certAlias)) { - X509Certificate[] ret = delegate.getCertificateChain(certAlias); - LOG.debug("Certificate Chain: {}", Arrays.toString(ret)); - return ret; + return delegate.getCertificateChain(certAlias); } else { - LOG.warn("Invalid certAlias '{}' in getCertificateChain() in class X509ExtendedKeyManager", certAlias); - LOG.warn("Expected: '{}'", this.certAlias); + LOG.warn("Different certAlias '{}' in getCertificateChain() in class X509ExtendedKeyManager, " + + "expected: '{}'", certAlias, this.certAlias); return null; } } @@ -119,8 +116,8 @@ public PrivateKey getPrivateKey(String certAlias) { if (certAlias.equals(this.certAlias)) { return delegate.getPrivateKey(certAlias); } else { - LOG.warn("Invalid certAlias '{}' in getPrivateKey() in class X509ExtendedKeyManager", certAlias); - LOG.warn("Expected: '{}'", this.certAlias); + LOG.warn("Different certAlias '{}' in getPrivateKey() in class X509ExtendedKeyManager, expected '{}'", + certAlias, this.certAlias); return null; } } From 8ff4beef11b1164434e64957b742372af542638a Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 28 May 2020 14:17:58 +0200 Subject: [PATCH 092/237] Improved/adjusted log outputs, added TODOs --- .../CustomX509ExtendedKeyManager.java | 14 +++++----- .../client/InputListenerThread.java | 2 +- .../secure_channel/client/TLSClient.java | 27 ++++++++++++++----- .../idscp2/example/Idscp2ServerInitiator.java | 2 +- .../idscp2/idscp_core/Idscp2Connection.java | 24 ++++++++++------- .../idscp_core/Idscp2ConnectionAdapter.java | 5 ++++ .../configuration/Idscp2ServerFactory.java | 1 + .../idscp_core/finite_state_machine/FSM.java | 12 ++++++--- .../secure_channel/SecureChannel.java | 8 ++++-- 9 files changed, 64 insertions(+), 31 deletions(-) diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java index 06173e5f7..92291cb56 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/keystores/CustomX509ExtendedKeyManager.java @@ -59,14 +59,12 @@ public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket s return this.certAlias; } else { LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); - return null; } - } else { - LOG.warn("Invalid keyType '{}' in chooseClientAlias() in class X509ExtendedKeyManager", - Arrays.toString(keyTypes)); - LOG.warn("Expected: '{}'", this.keyType); - return null; + } else if (LOG.isTraceEnabled()) { + LOG.trace("Different keyType '{}' in chooseClientAlias() in CustomX509ExtendedKeyManager, expected '{}'", + keyType, this.keyType); } + return null; } @Override @@ -89,8 +87,8 @@ public String chooseServerAlias(String keyType, Principal[] issuers, Socket sock } else { LOG.warn("certAlias '{}' was not found in keystore", this.certAlias); } - } else if (LOG.isDebugEnabled()) { - LOG.debug("Different keyType '{}' in chooseServerAlias() in CustomX509ExtendedKeyManager, expected '{}'", + } else if (LOG.isTraceEnabled()) { + LOG.trace("Different keyType '{}' in chooseServerAlias() in CustomX509ExtendedKeyManager, expected '{}'", keyType, this.keyType); } return null; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java index 49f9f6302..bd7572a80 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/InputListenerThread.java @@ -40,7 +40,7 @@ public void run() { //timeout to catch safeStop() call } catch (EOFException e) { listener.onClose(); - running = false; //terminate + running = false; } catch (IOException e) { listener.onError(e); running = false; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java index 03065d17f..997b5f6ba 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/secure_channel/client/TLSClient.java @@ -108,7 +108,7 @@ public void connect(String hostname, int port) { out = new DataOutputStream(clientSocket.getOutputStream()); - //add inputListener but start it not before handshake is complete + // Add inputListener but start it not before handshake is complete inputListenerThread = new InputListenerThread(clientSocket.getInputStream()); inputListenerThread.register(this); @@ -116,9 +116,11 @@ public void connect(String hostname, int port) { LOG.debug("Start TLS Handshake"); sslSocket.startHandshake(); } catch (SSLHandshakeException | SSLProtocolException e) { + // FIXME: Any such disconnect makes the server maintain a broken connection disconnect(); throw new Idscp2Exception("TLS Handshake failed", e); } catch (IOException e) { + // FIXME: Any such disconnect makes the server maintain a broken connection disconnect(); throw new Idscp2Exception("Connecting TLS client to server failed", e); } @@ -185,21 +187,32 @@ public void handshakeCompleted(HandshakeCompletedEvent handshakeCompletedEvent) LOG.debug("TLS Handshake was successful"); } + if (!this.connectionFuture.isCancelled()) { + // TODO: When server behavior fixed, disconnect and return here instantly +// disconnect(); +// return; + } + // verify tls session on application layer: hostname verification, certificate validity try { TLSSessionVerificationHelper.verifyTlsSession(handshakeCompletedEvent.getSession()); LOG.debug("TLS session is valid"); + // Create secure channel, register secure channel as message listener and notify IDSCP2 Configuration. + SecureChannel secureChannel = new SecureChannel(this); + this.listenerPromise.complete(secureChannel); + final var connection = new Idscp2Connection(secureChannel, clientSettings, dapsDriver); + inputListenerThread.start(); + // Try to complete, won't do anything if promise has been cancelled + this.connectionFuture.complete(connection); + if (this.connectionFuture.isCancelled()) { + connection.close(); + } } catch (SSLPeerUnverifiedException e) { + // FIXME: Any such disconnect makes the server maintain a broken connection disconnect(); connectionFuture.completeExceptionally( new Idscp2Exception("TLS session is not valid. Close TLS connection", e)); } - - // Create secure channel, register secure channel as message listener and notify IDSCP2 Configuration. - SecureChannel secureChannel = new SecureChannel(this); - this.listenerPromise.complete(secureChannel); - this.connectionFuture.complete(new Idscp2Connection(secureChannel, clientSettings, dapsDriver)); - inputListenerThread.start(); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java index 5ad62b29e..4993ea47f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/example/Idscp2ServerInitiator.java @@ -70,7 +70,7 @@ public void init(Idscp2Settings settings) { // Thread.sleep(40_000); //run server for 2 minutes // } catch (Exception ignored) { // } finally { -// idscp2Server.terminate(); +// idscp2Server.closeConnection(); // } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java index e8860d1a4..0593f822c 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2Connection.java @@ -10,6 +10,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; /** * The IDSCP2 Connection class holds connections between connectors @@ -37,7 +38,14 @@ public Idscp2Connection(SecureChannel secureChannel, Idscp2Settings settings, Da settings.getExpectedAttestation().getRatMechanisms(), settings.getRatTimeoutDelay()); secureChannel.setFsm(fsm); - LOG.debug("A new IDSCP2 connection with id {} was created, starting handshake...", connectionId); + if (LOG.isDebugEnabled()) { + LOG.debug("A new IDSCP2 connection with id {} was created, starting handshake...", connectionId); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Stack Trace of Idscp2Connection {} constructor:\n" + + Arrays.stream(Thread.currentThread().getStackTrace()) + .skip(1).map(Object::toString).collect(Collectors.joining("\n")), connectionId); + } // Schedule IDSCP handshake asynchronously CompletableFuture.runAsync(fsm::startIdscpHandshake); } @@ -51,11 +59,7 @@ public void unlockMessaging() { */ public void close() { LOG.debug("Closing connection {}...", connectionId); - // If server connection, this also unregisters the connection from the server. - if (fsm.isNotClosed()) { - connectionListeners.forEach(l -> l.onClose(this)); - } - fsm.terminate(); + fsm.closeConnection(); LOG.debug("IDSCP2 connection {} closed", connectionId); } @@ -63,14 +67,16 @@ public void close() { * Send data to the peer IDSCP2 connector */ public void send(String type, byte[] msg) { - LOG.debug("Send data of type \"" + type + "\" "); + LOG.debug("Send data of type \"" + type + "\" via connection {}", connectionId); fsm.send(type, msg); } public void onMessage(String type, byte[] msg) { // When unlock is called, although not synchronized, this will eventually stop blocking. messageLatch.await(); - LOG.debug("Received new IDSCP Message: " + Arrays.toString(msg)); + if (LOG.isTraceEnabled()) { + LOG.trace("Received new IDSCP Message"); + } genericMessageListeners.forEach(l -> l.onMessage(this, type, msg)); Set listeners = messageListeners.get(type); if (listeners != null) { @@ -86,7 +92,7 @@ public void onError(Throwable t) { } public void onClose() { - LOG.debug("Connection with id {} has been closed, notify listeners", connectionId); + LOG.debug("Connection with id {} is closing, notify listeners...", connectionId); connectionListeners.forEach(l -> l.onClose(this)); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java index d45391ea8..2f348da8a 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/Idscp2ConnectionAdapter.java @@ -1,9 +1,14 @@ package de.fhg.aisec.ids.idscp2.idscp_core; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Idscp2ConnectionAdapter implements Idscp2ConnectionListener { + private static final Logger LOG = LoggerFactory.getLogger(Idscp2ConnectionAdapter.class); @Override public void onError(Throwable t) { + LOG.error("Error received in Idscp2ConnectionAdapter", t); } @Override diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java index 9de609093..c79b37b60 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/configuration/Idscp2ServerFactory.java @@ -79,6 +79,7 @@ public void onClose(Idscp2Connection connection) { }); }); endpointListener.onConnection(newConnection); + // Listeners have been applied in onConnection() callback above, so we can safely unlock messaging now newConnection.unlockMessaging(); } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java index 21ddf8a68..7a1e2a14e 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/finite_state_machine/FSM.java @@ -354,7 +354,7 @@ private void feedEvent(Event event) { * The checkForFsmCircles method first checks for risky thread circles that occur by incorrect * driver implementations */ - public void terminate() { + public void closeConnection() { //check for incorrect usage checkForFsmCircles(); @@ -574,11 +574,15 @@ void stopRatProverDriver() { /* * Lock the fsm forever, terminate the timers and drivers, close the secure channel - * and notify User or handshake lock about closure + * and notify handshake lock if necessary */ void shutdownFsm() { LOG.debug("Shutting down FSM of connection {}...", connection.getId()); + if (LOG.isTraceEnabled()) { + LOG.trace("Running close handlers of connection {}...", connection.getId()); + } + connection.onClose(); if (LOG.isTraceEnabled()) { LOG.trace("Closing secure channel of connection {}...", connection.getId()); } @@ -615,7 +619,9 @@ void shutdownFsm() { */ void notifyIdscpMsgListener(String type, byte[] data) { this.connection.onMessage(type, data); - LOG.debug("Idscp data has been passed to connection listener"); + if (LOG.isTraceEnabled()) { + LOG.trace("Idscp data of type \"{}\" has been passed to connection listener", type); + } } // diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java index ffae9c55a..16ddd2590 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/idscp_core/secure_channel/SecureChannel.java @@ -35,13 +35,17 @@ public void close() { * return true if the data has been sent successfully, else false */ public boolean send(byte[] msg) { - LOG.debug("Send message via secure channel"); + if (LOG.isTraceEnabled()) { + LOG.trace("Send message via secure channel"); + } return endpoint.send(msg); } @Override public void onMessage(byte[] data) { - LOG.debug("New raw data has been received via the secure channel"); + if (LOG.isTraceEnabled()) { + LOG.trace("New raw data has been received via the secure channel"); + } fsmPromise.thenAccept(fsmListener -> fsmListener.onMessage(data)); } From 8eba384948688f0a9de0898986780ad4102284c9 Mon Sep 17 00:00:00 2001 From: Michael Lux Date: Thu, 28 May 2020 14:41:19 +0200 Subject: [PATCH 093/237] Endpoint parameterization, finished client/server side examples --- .../ids/camel/idscp2/RefCountingHashMap.kt | 77 ++++++++++++ .../idscp2/client/Idscp2ClientConsumer.kt | 32 +++-- .../idscp2/client/Idscp2ClientEndpoint.kt | 118 +++++++++++++----- .../idscp2/client/Idscp2ClientProducer.kt | 22 ++-- .../camel/idscp2/server/CamelIdscp2Server.kt | 20 ++- .../idscp2/server/Idscp2ServerComponent.kt | 34 ++--- .../idscp2/server/Idscp2ServerEndpoint.kt | 72 ++++++++--- .../example-idscp2-client-broadcast.xml | 28 +++++ .../route-examples/example-idscp2-client.xml | 21 +++- .../example-idscp2-server-broadcast.xml | 33 +++++ .../route-examples/example-idscp2-server.xml | 13 +- 11 files changed, 358 insertions(+), 112 deletions(-) create mode 100644 camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/RefCountingHashMap.kt create mode 100644 examples/route-examples/example-idscp2-client-broadcast.xml create mode 100644 examples/route-examples/example-idscp2-server-broadcast.xml diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/RefCountingHashMap.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/RefCountingHashMap.kt new file mode 100644 index 000000000..6c7fa5a1b --- /dev/null +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/RefCountingHashMap.kt @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.fhg.aisec.ids.camel.idscp2 + +/** + * A wrapped, synchronized HashMap counting the number of references to its values. + * When all references are released, releaseFunction will be called to finalize the freed value. + * + * @author Michael Lux + * + * @param releaseFunction The function used to finalize elements without remaining references. + */ +class RefCountingHashMap(private val releaseFunction: (V) -> Unit) { + private val map = HashMap>() + + /** + * Increments the reference count of an existing element + * or inserts the element newly created by mappingFunction with reference count 1. + * + * @param key The key of the element to be retrieved (w. increased reference count) + * or created with reference count 1. + * @param mappingFunction The function to create the element if it doesn't exist + */ + @Synchronized + fun computeIfAbsent(key: K, mappingFunction: (K) -> V): V { + return map[key]?.let { + map[key] = Pair(it.first + 1, it.second) + it.second + } ?: let { + val value = mappingFunction(key) + map[key] = Pair(1, value) + value + } + } + + /** + * Decrements the reference count of an existing element, + * deleting it and finalizing it using releaseFunction if reference count becomes zero. + */ + @Synchronized + fun release(key: K) { + map[key]?.let { + if (it.first == 1) { + releaseFunction(it.second) + map.remove(key) + } else { + map[key] = Pair(it.first - 1, it.second) + } + } + } + + /** + * Frees all resources (using releaseFunction) and clears the map. + * + * @param parallel Whether to use parallelStream() (default) or just stream() for iteration + */ + @Synchronized + fun freeAll(parallel: Boolean = true) { + map.values.let { if (parallel) it.parallelStream() else it.stream() } + .forEach { releaseFunction(it.second) } + map.clear() + } +} \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt index 563df78cf..2ba59579d 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientConsumer.kt @@ -17,6 +17,7 @@ package de.fhg.aisec.ids.camel.idscp2.client import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2MessageListener import org.apache.camel.Processor import org.apache.camel.support.DefaultConsumer @@ -28,23 +29,30 @@ import java.util.concurrent.CompletableFuture */ class Idscp2ClientConsumer(private val endpoint: Idscp2ClientEndpoint, processor: Processor) : DefaultConsumer(endpoint, processor), Idscp2MessageListener { - private val connectionFuture = CompletableFuture() + private lateinit var connectionFuture: CompletableFuture override fun doStart() { super.doStart() - endpoint.makeConnection(connectionFuture) - connectionFuture.thenAccept { it.addGenericMessageListener(this) } + connectionFuture = endpoint.makeConnection() + connectionFuture.thenAccept { + it.addGenericMessageListener(this) + // Handle connection errors and closing + it.addConnectionListener(object : Idscp2ConnectionListener { + override fun onError(t: Throwable?) { + LOG.error("Error in Idscp2ClientConsumer connection", t) + } + override fun onClose(connection: Idscp2Connection) { + stop() + } + }) + it.unlockMessaging() + } } public override fun doStop() { - if (connectionFuture.isDone) { - val connection = connectionFuture.get() - LOG.debug("Stopping IDSCP2 client connection {}...", connection.id) - connection.close() - } else { - LOG.debug("Canceling IDSCP2 client connection...") - connectionFuture.cancel(true) - } + LOG.debug("Stopping/releasing IDSCP2 client consumer connection {}...", + if (connectionFuture.isDone) connectionFuture.get().id else "") + endpoint.releaseConnection(connectionFuture) } override fun onMessage(connection: Idscp2Connection, type: String, data: ByteArray) { @@ -62,8 +70,6 @@ class Idscp2ClientConsumer(private val endpoint: Idscp2ClientEndpoint, processor if (response.body != null && responseType != null) { connection.send(responseType, response.getBody(ByteArray::class.java)) } - } catch (e: Exception) { - LOG.error("Error in Idscp2ClientConsumer.onMessage()", e) } finally { doneUoW(exchange) } diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt index 3f923369e..675a44fc3 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt @@ -18,6 +18,7 @@ package de.fhg.aisec.ids.camel.idscp2.client import de.fhg.aisec.ids.api.settings.Settings import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent +import de.fhg.aisec.ids.camel.idscp2.RefCountingHashMap import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriver import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.daps.DefaultDapsDriverConfig import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.secure_channel.NativeTLSDriver @@ -27,7 +28,9 @@ import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings import org.apache.camel.Processor import org.apache.camel.Producer import org.apache.camel.spi.UriEndpoint +import org.apache.camel.spi.UriParam import org.apache.camel.support.DefaultEndpoint +import org.apache.camel.support.jsse.SSLContextParameters import org.slf4j.LoggerFactory import java.util.concurrent.CompletableFuture import java.util.regex.Pattern @@ -38,41 +41,51 @@ import java.util.regex.Pattern syntax = "idscp2client://host:port", label = "ids" ) -class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2ClientComponent?) : +class Idscp2ClientEndpoint(uri: String?, private val remaining: String, component: Idscp2ClientComponent?) : DefaultEndpoint(uri, component) { - private val dapsDriverConfig: DefaultDapsDriverConfig - private val clientSettings: Idscp2Settings + private lateinit var dapsDriverConfig: DefaultDapsDriverConfig + private lateinit var clientSettings: Idscp2Settings - init { - val settings: Settings = Idscp2OsgiComponent.getSettings() - val remainingMatcher = URI_REGEX.matcher(remaining) - require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } - val matchResult = remainingMatcher.toMatchResult() - val host = matchResult.group(1) - val port = matchResult.group(2).toInt() - clientSettings = Idscp2Settings.Builder() - .setHost(host) - .setServerPort(port) - .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") - .setTrustStorePath("etc/idscp2/client-truststore_new.jks") - .setCertificateAlias("1.0.1") - .setDapsKeyAlias("1") - .setRatTimeoutDelay(300) - .build() - dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID(settings.connectorConfig.connectorUUID) - .setKeyStorePath(clientSettings.keyStorePath) - .setTrustStorePath(clientSettings.trustStorePath) - .setKeyStorePassword(clientSettings.keyStorePassword) - .setTrustStorePassword(clientSettings.trustStorePassword) - .setKeyAlias(clientSettings.dapsKeyAlias) - .setDapsUrl(settings.connectorConfig.dapsUrl) - .build() - } + @UriParam( + label = "security", + description = "The SSL context for the IDSCP2 endpoint" + ) + var sslContextParameters: SSLContextParameters? = null + @UriParam( + label = "security", + description = "The alias of the DAPS key in the keystore provided by sslContextParameters" + ) + var dapsKeyAlias: String? = null + @UriParam( + label = "security", + description = "The validity time of remote attestation and DAT in seconds", + defaultValue = "600" + ) + var dapsRatTimeoutDelay: Long? = null + @UriParam( + label = "client", + description = "Used to make N endpoints share the same connection, " + + "e.g. for using a consumer to receive responses to the requests of another producer" + ) + var connectionShareId: String? = null - fun makeConnection(connectionFuture: CompletableFuture) { - return Idscp2ClientFactory(DefaultDapsDriver(dapsDriverConfig), NativeTLSDriver()) + private fun makeConnectionInternal(): CompletableFuture { + val connectionFuture = CompletableFuture() + Idscp2ClientFactory(DefaultDapsDriver(dapsDriverConfig), NativeTLSDriver()) .connect(clientSettings, connectionFuture) + return connectionFuture + } + + fun makeConnection(): CompletableFuture { + connectionShareId?.let { + return sharedConnections.computeIfAbsent(it) { + makeConnectionInternal() + } + } ?: return makeConnectionInternal() + } + + fun releaseConnection(connectionFuture: CompletableFuture) { + connectionShareId?.let { sharedConnections.release(it) } ?: releaseConnectionInternal(connectionFuture) } override fun createProducer(): Producer { @@ -85,6 +98,37 @@ class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2Cli public override fun doStart() { LOG.debug("Starting IDSCP2 client endpoint $endpointUri") + val settings: Settings = Idscp2OsgiComponent.getSettings() + val remainingMatcher = URI_REGEX.matcher(remaining) + require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } + val matchResult = remainingMatcher.toMatchResult() + val host = matchResult.group(1) + val port = matchResult.group(2)?.toInt() ?: Idscp2Settings.DEFAULT_SERVER_PORT + val clientSettingsBuilder = Idscp2Settings.Builder() + .setHost(host) + .setServerPort(port) + .setRatTimeoutDelay(dapsRatTimeoutDelay ?: Idscp2Settings.DEFAULT_RAT_TIMEOUT_DELAY.toLong()) + .setDapsKeyAlias(dapsKeyAlias ?: "1") + sslContextParameters?.let { + clientSettingsBuilder + .setKeyPassword(it.keyManagers?.keyPassword ?: "password") + .setKeyStorePath(it.keyManagers?.keyStore?.resource) + .setKeyStoreKeyType(it.keyManagers?.keyStore?.type ?: "RSA") + .setKeyStorePassword(it.keyManagers?.keyStore?.password ?: "password") + .setTrustStorePath(it.trustManagers?.keyStore?.resource) + .setTrustStorePassword(it.trustManagers?.keyStore?.password ?: "password") + .setCertificateAlias(it.certAlias ?: "1.0.1") + } + clientSettings = clientSettingsBuilder.build() + dapsDriverConfig = DefaultDapsDriverConfig.Builder() + .setConnectorUUID(settings.connectorConfig.connectorUUID) + .setDapsUrl(settings.connectorConfig.dapsUrl) + .setKeyAlias(clientSettings.dapsKeyAlias) + .setKeyStorePath(clientSettings.keyStorePath) + .setTrustStorePath(clientSettings.trustStorePath) + .setKeyStorePassword(clientSettings.keyStorePassword) + .setTrustStorePassword(clientSettings.trustStorePassword) + .build() } public override fun doStop() { @@ -93,6 +137,16 @@ class Idscp2ClientEndpoint(uri: String?, remaining: String, component: Idscp2Cli companion object { private val LOG = LoggerFactory.getLogger(Idscp2ClientEndpoint::class.java) - private val URI_REGEX = Pattern.compile("(.*?):(\\d+)$") + private val URI_REGEX = Pattern.compile("(.*?)(?::(\\d+))?/?$") + private val sharedConnections = RefCountingHashMap> { connection -> + releaseConnectionInternal(connection) + } + private fun releaseConnectionInternal(connectionFuture: CompletableFuture) { + if (connectionFuture.isDone) { + connectionFuture.get().close() + } else if (!(connectionFuture.isCancelled || connectionFuture.isCompletedExceptionally)) { + connectionFuture.cancel(true) + } + } } } \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt index a8755252a..44a07a81d 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientProducer.kt @@ -27,32 +27,26 @@ import java.util.concurrent.CompletableFuture * Sends each message to all clients connected to this server endpoint. */ class Idscp2ClientProducer(private val endpoint: Idscp2ClientEndpoint) : DefaultProducer(endpoint) { - private val connectionFuture = CompletableFuture() + private lateinit var connectionFuture: CompletableFuture override fun process(exchange: Exchange) { val message = exchange.getIn() val type = message.getHeader("idscp2.type", String::class.java) val body = message.getBody(ByteArray::class.java) - connectionFuture.get().let { - it.unlockMessaging() - it.send(type, body) - } + connectionFuture.get().send(type, body) } override fun doStart() { super.doStart() - endpoint.makeConnection(connectionFuture) + connectionFuture = endpoint.makeConnection() + // Unlock messaging immediately after obtaining connection + connectionFuture.thenAccept { it.unlockMessaging() } } public override fun doStop() { - if (connectionFuture.isDone) { - val connection = connectionFuture.get() - LOG.debug("Stopping IDSCP2 client connection {}...", connection.id) - connection.close() - } else { - LOG.debug("Canceling IDSCP2 client connection...") - connectionFuture.cancel(true) - } + LOG.debug("Stopping/releasing IDSCP2 client producer connection {}...", + if (connectionFuture.isDone) connectionFuture.get().id else "") + endpoint.releaseConnection(connectionFuture) } companion object { diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt index 5a84164a4..b14e51298 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package de.fhg.aisec.ids.camel.idscp2.server import de.fhg.aisec.ids.camel.idscp2.Idscp2OsgiComponent @@ -18,12 +34,12 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener init { val dapsDriverConfig = DefaultDapsDriverConfig.Builder() .setConnectorUUID(Idscp2OsgiComponent.getSettings().connectorConfig.connectorUUID) + .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) + .setKeyAlias(serverSettings.dapsKeyAlias) .setKeyStorePath(serverSettings.keyStorePath) .setTrustStorePath(serverSettings.trustStorePath) .setKeyStorePassword(serverSettings.keyStorePassword) .setTrustStorePassword(serverSettings.trustStorePassword) - .setKeyAlias(serverSettings.dapsKeyAlias) - .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) .build() val serverConfiguration = Idscp2ServerFactory( this, diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt index f6f732f80..94f429453 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerComponent.kt @@ -16,6 +16,7 @@ */ package de.fhg.aisec.ids.camel.idscp2.server +import de.fhg.aisec.ids.camel.idscp2.RefCountingHashMap import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatProverDummy import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.dummy.RatVerifierDummy import de.fhg.aisec.ids.idscp2.drivers.default_driver_impl.rat.tpm2d.TPM2dProver @@ -28,11 +29,12 @@ import de.fhg.aisec.ids.idscp2.idscp_core.rat_registry.RatVerifierDriverRegistry import org.apache.camel.Endpoint import org.apache.camel.spi.annotations.Component import org.apache.camel.support.DefaultComponent -import java.lang.IllegalStateException @Component("idscp2server") class Idscp2ServerComponent : DefaultComponent() { - private val servers: MutableMap> = HashMap() + private val servers = RefCountingHashMap { + it.terminate() + } init { RatProverDriverRegistry.getInstance().registerDriver( @@ -56,36 +58,14 @@ class Idscp2ServerComponent : DefaultComponent() { } @Synchronized - fun getServer(serverSettings: Idscp2Settings): CamelIdscp2Server { - if (serverSettings in servers) { - servers[serverSettings]?.let { - servers[serverSettings] = Pair(it.first + 1, it.second) - return it.second - } ?: throw IllegalStateException("This should never happen, please inform developers of this error!") - } else { - val server = CamelIdscp2Server(serverSettings) - servers[serverSettings] = Pair(1, server) - return server - } - } + fun getServer(serverSettings: Idscp2Settings) = servers.computeIfAbsent(serverSettings) { CamelIdscp2Server(it) } @Synchronized - fun freeServer(serverSettings: Idscp2Settings) { - servers[serverSettings]?.let { - if (it.first > 1) { - servers[serverSettings] = Pair(it.first - 1, it.second) - } else { - it.second.terminate() - servers.remove(serverSettings) - } - } - } + fun freeServer(serverSettings: Idscp2Settings) = servers.release(serverSettings) @Synchronized override fun doStop() { - servers.values.parallelStream() - .forEach { it.second.terminate() } - servers.clear() + servers.freeAll() super.doStop() } } \ No newline at end of file diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt index 3c1f87f95..70e85dd6f 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/Idscp2ServerEndpoint.kt @@ -18,11 +18,14 @@ package de.fhg.aisec.ids.camel.idscp2.server import de.fhg.aisec.ids.idscp2.Idscp2EndpointListener import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2Connection +import de.fhg.aisec.ids.idscp2.idscp_core.Idscp2ConnectionListener import de.fhg.aisec.ids.idscp2.idscp_core.configuration.Idscp2Settings import org.apache.camel.Processor import org.apache.camel.Producer import org.apache.camel.spi.UriEndpoint +import org.apache.camel.spi.UriParam import org.apache.camel.support.DefaultEndpoint +import org.apache.camel.support.jsse.SSLContextParameters import org.slf4j.LoggerFactory import java.util.* import java.util.regex.Pattern @@ -33,28 +36,29 @@ import java.util.regex.Pattern syntax = "idscp2server://host:port", label = "ids" ) -class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2ServerComponent?) : +class Idscp2ServerEndpoint(uri: String?, private val remaining: String, component: Idscp2ServerComponent?) : DefaultEndpoint(uri, component), Idscp2EndpointListener { - private val serverSettings: Idscp2Settings + private lateinit var serverSettings: Idscp2Settings private var server: CamelIdscp2Server? = null private val consumers: MutableSet = HashSet() - init { - val remainingMatcher = URI_REGEX.matcher(remaining) - require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } - val matchResult = remainingMatcher.toMatchResult() - val host = matchResult.group(1) - val port = matchResult.group(2).toInt() - serverSettings = Idscp2Settings.Builder() - .setHost(host) - .setServerPort(port) - .setKeyStorePath("etc/idscp2/aisecconnector1-keystore.jks") - .setTrustStorePath("etc/idscp2/client-truststore_new.jks") - .setCertificateAlias("1.0.1") - .setDapsKeyAlias("1") - .setRatTimeoutDelay(300) - .build() - } + @UriParam( + label = "security", + description = "The SSL context for the IDSCP2 endpoint" + ) + var sslContextParameters: SSLContextParameters? = null + @UriParam( + label = "security", + description = "The alias of the DAPS key in the keystore provided by sslContextParameters", + defaultValue = "1" + ) + var dapsKeyAlias: String = "1" + @UriParam( + label = "security", + description = "The validity time of remote attestation and DAT in seconds", + defaultValue = "600" + ) + var dapsRatTimeoutDelay: Long = Idscp2Settings.DEFAULT_RAT_TIMEOUT_DELAY.toLong() @Synchronized fun addConsumer(consumer: Idscp2ServerConsumer) { @@ -87,6 +91,15 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser override fun onConnection(connection: Idscp2Connection) { LOG.debug("New IDSCP2 connection on $endpointUri, register consumer listeners") consumers.forEach { connection.addGenericMessageListener(it) } + // Handle connection errors and closing + connection.addConnectionListener(object : Idscp2ConnectionListener { + override fun onError(t: Throwable?) { + LOG.error("Error in Idscp2ServerEndpoint-managed connection", t) + } + override fun onClose(connection: Idscp2Connection) { + consumers.forEach { connection.removeGenericMessageListener(it) } + } + }) } override fun onError(t: Throwable) { @@ -96,6 +109,27 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser @Synchronized public override fun doStart() { LOG.debug("Starting IDSCP2 server endpoint $endpointUri") + val remainingMatcher = URI_REGEX.matcher(remaining) + require(remainingMatcher.matches()) { "$remaining is not a valid URI remainder, must be \"host:port\"." } + val matchResult = remainingMatcher.toMatchResult() + val host = matchResult.group(1) + val port = matchResult.group(2)?.toInt() ?: Idscp2Settings.DEFAULT_SERVER_PORT + val clientSettingsBuilder = Idscp2Settings.Builder() + .setHost(host) + .setServerPort(port) + .setRatTimeoutDelay(dapsRatTimeoutDelay) + .setDapsKeyAlias(dapsKeyAlias) + sslContextParameters?.let { + clientSettingsBuilder + .setKeyPassword(it.keyManagers?.keyPassword ?: "password") + .setKeyStorePath(it.keyManagers?.keyStore?.resource) + .setKeyStoreKeyType(it.keyManagers?.keyStore?.type ?: "RSA") + .setKeyStorePassword(it.keyManagers?.keyStore?.password ?: "password") + .setTrustStorePath(it.trustManagers?.keyStore?.resource) + .setTrustStorePassword(it.trustManagers?.keyStore?.password ?: "password") + .setCertificateAlias(it.certAlias ?: "1.0.1") + } + serverSettings = clientSettingsBuilder.build() (component as Idscp2ServerComponent).getServer(serverSettings).let { server = it // Add this endpoint to this server's Idscp2EndpointListener set @@ -113,6 +147,6 @@ class Idscp2ServerEndpoint(uri: String?, remaining: String, component: Idscp2Ser companion object { private val LOG = LoggerFactory.getLogger(Idscp2ServerEndpoint::class.java) - private val URI_REGEX = Pattern.compile("(.*?):(\\d+)$") + private val URI_REGEX = Pattern.compile("(.*?)(?::(\\d+))?/?$") } } \ No newline at end of file diff --git a/examples/route-examples/example-idscp2-client-broadcast.xml b/examples/route-examples/example-idscp2-client-broadcast.xml new file mode 100644 index 000000000..b9ca71854 --- /dev/null +++ b/examples/route-examples/example-idscp2-client-broadcast.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/route-examples/example-idscp2-client.xml b/examples/route-examples/example-idscp2-client.xml index eb7569ffd..b803ed2cd 100644 --- a/examples/route-examples/example-idscp2-client.xml +++ b/examples/route-examples/example-idscp2-client.xml @@ -1,13 +1,22 @@ + + + + + + + + + - + PING @@ -16,8 +25,14 @@ ping - + + + + + + + diff --git a/examples/route-examples/example-idscp2-server-broadcast.xml b/examples/route-examples/example-idscp2-server-broadcast.xml new file mode 100644 index 000000000..31aaffb0c --- /dev/null +++ b/examples/route-examples/example-idscp2-server-broadcast.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + BROADCAST + + + broadcast + + + + + + + + diff --git a/examples/route-examples/example-idscp2-server.xml b/examples/route-examples/example-idscp2-server.xml index 44f24e692..98a87f346 100644 --- a/examples/route-examples/example-idscp2-server.xml +++ b/examples/route-examples/example-idscp2-server.xml @@ -1,14 +1,23 @@ + + + + + + + + + - + PONG From 719383fd490f57919656bd50c647c8e180c3b44f Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 1 Jul 2020 20:34:34 +0200 Subject: [PATCH 094/237] hack to accept new DAT --- .../de/fhg/aisec/ids/tokenmanager/TokenManagerService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index a8f374fe3..c8870d859 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -258,7 +258,9 @@ public Map verifyJWT( .setRequireSubject() // the JWT must have a subject claim .setExpectedIssuer( "https://daps.aisec.fraunhofer.de") // whom the JWT needs to have been issued by - .setExpectedAudience(targetAudience) // to whom the JWT is intended for + //.setExpectedAudience(targetAudience) // to whom the JWT is intended for + //FIXME: Evil hack to support both audience types from DAPSv1 and v2. We need to get versioning going and we need to get it right. Until then, just hack in second value + .setExpectedAudience(targetAudience, "idsc:IDS_CONNECTORS_ALL") // to whom the JWT is intended for .setVerificationKeyResolver(httpsJwksKeyResolver) .setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the // given context From 0945263b0a4719653d30a50545f9cb8d63ba1fcb Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Mon, 6 Jul 2020 13:41:34 +0200 Subject: [PATCH 095/237] remove audience check without proper versioning --- .../aisec/ids/camel/ids/server/DefaultWebsocket.java | 5 +---- .../IdsClientServerPlaintextWithAttestationTest.java | 2 +- .../de/fhg/aisec/ids/api/tokenm/TokenManager.java | 1 - .../aisec/ids/tokenmanager/TokenManagerService.java | 12 ++++-------- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java index 5e9691df0..6163e3211 100644 --- a/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java +++ b/camel-ids/src/main/java/de/fhg/aisec/ids/camel/ids/server/DefaultWebsocket.java @@ -234,13 +234,10 @@ private void validateDynamicAttributeToken(@NonNull String dat) throws DatExcept ConnectionSettings connectionSettings = settings.getConnectionSettings(consumer.getEndpoint().getHost() + ":" + consumer.getEndpoint().getPort().toString()); - // This is a bug in the DAPS. - // Audience should not be set to default value "IDS_Connector" - String targetAudience = "IDS_Connector"; try { //validate token signature, target Audience, expire date - var claims = tokenManager.verifyJWT(dat, targetAudience, dapsUrl); + var claims = tokenManager.verifyJWT(dat, dapsUrl); //validate supported security attributes tokenManager.validateDATSecurityAttributes(claims, connectionSettings); } catch (Exception e) { diff --git a/camel-ids/src/test/java/de/fhg/aisec/ids/camel/ids/IdsClientServerPlaintextWithAttestationTest.java b/camel-ids/src/test/java/de/fhg/aisec/ids/camel/ids/IdsClientServerPlaintextWithAttestationTest.java index eacfd8287..560696cd2 100644 --- a/camel-ids/src/test/java/de/fhg/aisec/ids/camel/ids/IdsClientServerPlaintextWithAttestationTest.java +++ b/camel-ids/src/test/java/de/fhg/aisec/ids/camel/ids/IdsClientServerPlaintextWithAttestationTest.java @@ -56,7 +56,7 @@ public void mockRequiredBundles() throws Exception { when(settings.getConnectionSettings(anyString())).thenReturn(new ConnectionSettings()); cc.setSettings(settings); TokenManager tm = mock(TokenManager.class); - when(tm.verifyJWT(anyString(), anyString(), anyString())).thenReturn(Collections.emptyMap()); + when(tm.verifyJWT(anyString(), anyString())).thenReturn(Collections.emptyMap()); doNothing().when(tm).validateDATSecurityAttributes(any(), any(ConnectionSettings.class)); cc.setTokenManager(tm); CamelComponent.setInstance(cc); diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java index d0ecadc5c..5c3d45c0d 100755 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java @@ -45,7 +45,6 @@ Map acquireToken( Map verifyJWT( String dynamicAttributeToken, - String targetAudience, String dapsUrl) throws Exception; void validateDATSecurityAttributes( diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index c8870d859..f49126390 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -99,9 +99,7 @@ public Map acquireToken( String keystoreAliasName, String trustStoreName, String connectorUUID) { - // This is a bug in the DAPS. - // Audience should not be set to default value "IDS_Connector" - String targetAudience = "IDS_Connector"; + String dynamicAttributeToken = "INVALID_TOKEN"; Map jwtClaims = null; @@ -202,7 +200,7 @@ public Map acquireToken( LOG.info("Dynamic Attribute Token: " + dynamicAttributeToken); - jwtClaims = verifyJWT(dynamicAttributeToken, targetAudience, dapsUrl); + jwtClaims = verifyJWT(dynamicAttributeToken, dapsUrl); } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException @@ -222,7 +220,6 @@ public Map acquireToken( @Override public Map verifyJWT( String dynamicAttributeToken, - String targetAudience, String dapsUrl) throws Exception { if (sslSocketFactory == null) { throw new JwtException("SSLSocketFactory is null, acquireToken() must be called first!"); @@ -258,9 +255,8 @@ public Map verifyJWT( .setRequireSubject() // the JWT must have a subject claim .setExpectedIssuer( "https://daps.aisec.fraunhofer.de") // whom the JWT needs to have been issued by - //.setExpectedAudience(targetAudience) // to whom the JWT is intended for - //FIXME: Evil hack to support both audience types from DAPSv1 and v2. We need to get versioning going and we need to get it right. Until then, just hack in second value - .setExpectedAudience(targetAudience, "idsc:IDS_CONNECTORS_ALL") // to whom the JWT is intended for + //FIXME: Hardcoded two v1 and v2 values. Need to add versioning to correctly handle tokens. + .setExpectedAudience(true, "IDS_Connector", "idsc:IDS_CONNECTORS_ALL") // to whom the JWT is intended for .setVerificationKeyResolver(httpsJwksKeyResolver) .setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the // given context From 6d93ef67a0b0e4036e0e34d3c3eaa179f662121b Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Mon, 6 Jul 2020 14:10:15 +0200 Subject: [PATCH 096/237] fix audience --- .../de/fhg/aisec/ids/tokenmanager/TokenManagerService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index f49126390..2963f25d0 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -101,6 +101,8 @@ public Map acquireToken( String connectorUUID) { String dynamicAttributeToken = "INVALID_TOKEN"; + String targetAudience = "IDS_Connector"; + Map jwtClaims = null; // Try clause for setup phase (loading keys, building trust manager) @@ -146,6 +148,7 @@ public Map acquireToken( throw new RuntimeException(e); } + LOG.info("Retrieving Dynamic Attribute Token..."); // create signed JWT (JWS) From b4a83bc62a769544a683e0c9ac8f6b68afe77ff2 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 10:08:32 +0200 Subject: [PATCH 097/237] retrieve DAPSv2 token --- .../ids/tokenmanager/TokenManagerService.java | 54 +++++++++++------- .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index 2963f25d0..68e07c2f1 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -57,6 +57,7 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Map; @@ -116,7 +117,7 @@ public Map acquireToken( KeyStore trustManagerKeyStore = KeyStore.getInstance("JKS"); LOG.info("Loading key store: " + keyStoreName); - LOG.info("Loading trus store: " + trustStoreName); + LOG.info("Loading trust store: " + trustStoreName); keystore.load(jksKeyStoreInputStream, keyStorePassword.toCharArray()); trustManagerKeyStore.load(jksTrustStoreInputStream, keyStorePassword.toCharArray()); java.security.cert.Certificate[] certs = trustManagerKeyStore.getCertificateChain("ca"); @@ -131,6 +132,8 @@ public Map acquireToken( // Get certificate of public key X509Certificate cert = (X509Certificate) keystore.getCertificate(keystoreAliasName); + + TrustManager[] trustManagers; try { TrustManagerFactory trustManagerFactory = @@ -148,9 +151,17 @@ public Map acquireToken( throw new RuntimeException(e); } - + LOG.info("\tCertificate Subject: " + cert.getSubjectDN()); + //GET 2.5.29.14 SubjectKeyIdentifier / 2.5.29.35 AuthorityKeyIdentifier + String authorityKeyIndentifier = new String (cert.getExtensionValue("2.5.29.35")); + String subjectKeyIdenfier = new String (cert.getExtensionValue("2.5.29.14")); + LOG.info("AKI: " + authorityKeyIndentifier); + LOG.info("SKI: " + subjectKeyIdenfier); + //connectorUUID = subjectKeyIdenfier + ":" + authorityKeyIndentifier.substring(0, authorityKeyIndentifier.length() - 1); + LOG.info("ConnectorUUID: " + connectorUUID); LOG.info("Retrieving Dynamic Attribute Token..."); + // create signed JWT (JWS) // Create expiry date one day (86400 seconds) from now Date expiryDate = Date.from(Instant.now().plusSeconds(86400)); @@ -158,12 +169,15 @@ public Map acquireToken( Jwts.builder() .setIssuer(connectorUUID) .setSubject(connectorUUID) + .claim("@context", "https://w3id.org/idsa/contexts/context.jsonld") + .claim("@type", "ids:DatRequestToken") .setExpiration(expiryDate) .setIssuedAt(Date.from(Instant.now())) .setAudience(targetAudience) .setNotBefore(Date.from(Instant.now())); - LOG.info("\tCertificate Subject: " + cert.getSubjectDN()); + String jws = jwtb.signWith(privKey, SignatureAlgorithm.RS256).compact(); + LOG.info("Request token: " + jws); // build form body to embed client assertion into post request RequestBody formBody = @@ -172,7 +186,7 @@ public Map acquireToken( .add( "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") .add("client_assertion", jws) - .add("scope", "ids_connector") + .add("scope", "idsc:IDS_CONNECTOR_ATTRIBUTES_ALL") .build(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); @@ -186,7 +200,7 @@ public Map acquireToken( .readTimeout(15, TimeUnit.SECONDS) .build(); - Request request = new Request.Builder().url(dapsUrl + "/token").post(formBody).build(); + Request request = new Request.Builder().url(dapsUrl + "/v2/token").post(formBody).build(); Response jwtResponse = client.newCall(request).execute(); if (!jwtResponse.isSuccessful()) { throw new IOException("Unexpected code " + jwtResponse); @@ -310,24 +324,22 @@ public Map verifyJWT( public void validateDATSecurityAttributes(Map claims, ConnectionSettings connectionSettings) throws DatException { try { - Object idsAttributesObject = claims.get("ids_attributes"); - Map securityProfile; - if (idsAttributesObject instanceof Map) { - var securityProfileObject = ((Map) idsAttributesObject).get("security_profile"); - if (securityProfileObject instanceof Map) { - securityProfile = (Map) securityProfileObject; - } else { - throw new DatException("No security_profile found in claims " + securityProfileObject); - } - } else { - throw new DatException("No ids_attributes claims found in claims " + idsAttributesObject); - } - // Validate audit_logging - var auditLogging = Integer.parseInt(securityProfile.get("audit_logging").toString()); - if (Integer.parseInt(connectionSettings.getAuditLogging()) > auditLogging) { - throw new DatException("Client does not support the security requirements for audit_logging."); + String securityProfile = claims.get("securityProfile").toString(); + + //FIXME: Validate security profile the proper way + + ArrayList validTrustProfiles=new ArrayList(); + validTrustProfiles.add("idsc:TRUST_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:BASE_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:TRUST+_SECURITY_PROFILE"); + + if (!validTrustProfiles.contains(securityProfile)) { + throw new DatException("Client does not support valid trust profile."); } + //TODO Check for trust profile + //if (Integer.parseInt(connectionSettings.getAuditLogging()) > auditLogging) { + // throw new DatException("Client does not support the security requirements for audit_logging."); // TODO: validate further security attributes } catch (NumberFormatException e) { diff --git a/karaf-assembly/src/main/resources/etc/settings.mapdb b/karaf-assembly/src/main/resources/etc/settings.mapdb index 937ee9b5ed76d41326329502fa6b8e39c9cd60af..d2098f4a3bf0822e9f3344dd1de9e68b31263155 100644 GIT binary patch delta 1690 zcmbtUOOM-B6wY*}%nU7^DX0ReELb2Gm5M+}ERm2{!KM;_fGsS5k=P+M8FkT0P!&{F z-4y%`sU$I>3U(k^(T7g>z(~8#s2+6{MpX+JzTx~ z){px)3e9c*aaQ^2gWXTJ=08eDg)Dtp+JUlkv|GAXocBN4yI05$XQi8kyiMObIlX^! zx&v_uVi#f$;xfc55c?1Z5Qh-2LR^8k3h^4mwff2FQTOhXJIBXI4;~6~ztItxGhJ!3 zGV$H6^ z8mJMViWiw#^1)N*z2k@F2Zxp6Mnr~IBTxdd-AC1+LyI%lREu-un9g`$t`Q+v1-7}K z2w@r+v9ytOJ2+RL!_eF@Wz6tFdjxMU_!*hg(68hXlW}YAeXio7lp$A*w>vzi#?Mp z_%;Tuc;)njnvleipJ%LXX{v3-7aqn%1$UK~m)=B+hpp|swt4+LU6wnzpTo;8JY1Y~ zFc^%nOBaPc+7{M8rqs)Yb)54j_qew6;Sw zS9m#;O%=0qVP9xTz|o~LA%!DM!lbp6sJVn0RY?~R31bll-cDv< z+OQcZrk2=Yqqu1f$*mkq3Y7RFa7`_@^Gwt@`CLUPMUVPSpQU;h!Wn%|6xFzIXnkli z){+n-7ed0J4*jA_m{jW-WlgsbxvNJ6oR8Ku;up@aWv(UX#kk#;hWIV1*4a>zZ8h^w z!eu_z4?Bsov912X<*CH6goOj=UJx9Z+tINalQC+T@fwq^)G#HaJgv%1nnSsg^mHxh z8K;)R6on21G!&>ROh#*ZiYrWtLp>_z8L#FkqUzbqvEt0xCQYkqo-xoy%OOl!`0H5{ z#%!cKYsz6!I9*(|hQ)kRzIXYjo z6`>JaNHc+4*($Yecz-#=iR$75cB;?Bvcmg*o%S^{Z)Y2NNiu9aq%Y!jw<&NFbl}(O z&T2Y~;*~q6)uog1c1VTUA~6@ixiN3J@Hq8eg64Brzxv> delta 275 zcmXBOJqp4w7{>9WAJ+QSIEaEv2d7FWFW?Onynw57aS}>i<)w>5wRj0Psp1s`2k{Vs zZXUs>HSp&p3HcGNwbUr>^e3;gD3%IukR&g5~Pt%3WKX%W`pLTEM zsNz&a*;mhf<6Ue9k?_jHnUI*mGyhMW(S|4?lE^?NvXG4`$U#-)q8h5B25O?#mB@R< zSxW80RH From 80a360708e5a54584bb47cf216933ed60531ae03 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 098/237] upgraded to DAPSv2 --- buildx/docker-buildx.sh | 0 .../ids/api/infomodel/ConnectorProfile.java | 2 +- .../ids/api/settings/ConnectionSettings.java | 49 +-- .../InfoModelService.kt | 2 +- .../ids/tokenmanager/TokenManagerService.java | 38 +- .../connection-configuration/configuration.ts | 9 +- .../connection-configuration.component.html | 342 +----------------- .../settings.interface.ts | 9 +- .../daps/DefaultDapsDriver.java | 67 ++-- .../daps/SecurityRequirements.java | 10 +- .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes 11 files changed, 110 insertions(+), 418 deletions(-) mode change 100644 => 100755 buildx/docker-buildx.sh diff --git a/buildx/docker-buildx.sh b/buildx/docker-buildx.sh old mode 100644 new mode 100755 diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java index e1d5c0032..d6c13d6c8 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/infomodel/ConnectorProfile.java @@ -35,7 +35,7 @@ public final class ConnectorProfile implements Serializable { private List connectorEntityNames; public ConnectorProfile() { - this.securityProfile = SecurityProfile.BASE_CONNECTOR_SECURITY_PROFILE; + this.securityProfile = SecurityProfile.TRUSTED_CONNECTOR_SECURITY_PROFILE; this.connectorUrl = null; this.maintainerUrl = null; this.connectorEntityNames = null; diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java index 92438d7fc..5622f839a 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectionSettings.java @@ -24,55 +24,14 @@ public final class ConnectionSettings implements Serializable { private static final long serialVersionUID = 1L; - private final String integrityProtectionAndVerification; - private final String authentication; - private final String serviceIsolation; - private final String integrityProtectionVerificationScope; - private final String appExecutionResources; - private final String dataUsageControlSupport; - private final String auditLogging; - private final String localDataConfidentiality; + private final String securityProfile; public ConnectionSettings() { - integrityProtectionAndVerification = "1"; - authentication = "1"; - serviceIsolation = "1"; - integrityProtectionVerificationScope = "1"; - appExecutionResources = "1"; - dataUsageControlSupport = "1"; - auditLogging = "1"; - localDataConfidentiality = "1"; + securityProfile = "1"; } - public String getIntegrityProtectionAndVerification() { - return integrityProtectionAndVerification; + public String getRequiredSecurityProfile() { + return securityProfile; } - public String getAuthentication() { - return authentication; - } - - public String getServiceIsolation() { - return serviceIsolation; - } - - public String getIntegrityProtectionVerificationScope() { - return integrityProtectionVerificationScope; - } - - public String getAppExecutionResources() { - return appExecutionResources; - } - - public String getDataUsageControlSupport() { - return dataUsageControlSupport; - } - - public String getAuditLogging() { - return auditLogging; - } - - public String getLocalDataConfidentiality() { - return localDataConfidentiality; - } } diff --git a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt index c51fb8a15..6c3b3c7ce 100644 --- a/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt +++ b/ids-infomodel-manager/src/main/kotlin/de/fhg/aisec/ids/informationmodelmanager/InfoModelService.kt @@ -117,7 +117,7 @@ class InfoModelService : InfoModel { // generates RDF description from Connector object and returns building success override fun setConnector(profile: ConnectorProfile): Boolean { if (profile.securityProfile == null) { - profile.securityProfile = SecurityProfile.BASE_CONNECTOR_SECURITY_PROFILE + profile.securityProfile = SecurityProfile.TRUSTED_CONNECTOR_SECURITY_PROFILE } return if (settings != null) { settings?.connectorProfile = profile diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index 68e07c2f1..a61a9c380 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -338,8 +338,42 @@ public void validateDATSecurityAttributes(Map claims, Connection throw new DatException("Client does not support valid trust profile."); } //TODO Check for trust profile - //if (Integer.parseInt(connectionSettings.getAuditLogging()) > auditLogging) { - // throw new DatException("Client does not support the security requirements for audit_logging."); + + if(connectionSettings.getRequiredSecurityProfile().equals("idsc:BASE_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:BASE_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + + throw new DatException( + "Client does not support required trust profile: Required: " + + connectionSettings.getRequiredSecurityProfile() + + " given: " + + securityProfile); + } + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") && + !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + throw new DatException( + "Client does not support required trust profile: Required: " + + connectionSettings.getRequiredSecurityProfile() + + " given: " + + securityProfile); + } + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST+_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + throw new DatException( + "Client does not support required trust profile: Required: " + + connectionSettings.getRequiredSecurityProfile() + + " given: " + + securityProfile); + } + } else { + throw new DatException( + "Client does not support any valid trust profile: Required: " + + connectionSettings.getRequiredSecurityProfile() + + " given: " + + securityProfile); + } // TODO: validate further security attributes } catch (NumberFormatException e) { diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts index 7851c8738..68b8ae162 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts @@ -11,14 +11,7 @@ export class Configuration { this.settings = settings; } else { this.settings = { - integrityProtectionAndVerification: '1', - authentication: '1', - serviceIsolation: '1', - integrityProtectionVerificationScope: '1', - appExecutionResources: '1', - dataUsageControlSupport: '1', - auditLogging: '1', - localDataConfidentiality: '1' + securityProfile: 'idsc:BASE_SECURITY_PROFILE' }; } } diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html index 17cd095cf..e2886832b 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html @@ -27,72 +27,26 @@

Endpoint Security Requirements

Loading Settings...

- + @@ -100,281 +54,25 @@
Authentication
- + [(ngModel)]="model.settings.securityProfile" + name="securityProfile" + [value]="'idsc:BASE_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:BASE_SECURITY_PROFILE'"/> + - + [(ngModel)]="model.settings.securityProfile" + name="securityProfile" + [value]="'idsc:TRUST_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUST_SECURITY_PROFILE'"/> + - + [(ngModel)]="model.settings.securityProfile" + name="securityProfile" + [value]="'idsc:TRUST+_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUST+_SECURITY_PROFILE'"/> +
- - - - - - - - - - - - - - - - - - - - -
-
Authentication
+
Required Security Profile
  • - None - No endpoint authentication required. Connections are encrypted, but authenticity of the communication partner cannot be guaranteed. Data may be sent to malicious endpoints. + BASE Security Profile + BASE security profile required. Lower security requirements for incoming connection requests.
  • - Server Authentication - Authenticity of the server must be guaranteed. Authenticity of the client is not checked. + TRUST Security Profile + TRUST security profile required. High security requirments for incoming connection requests.
  • - Mutual Authentication - Authenticity of server and client must be guaranteed. + TRUST+ Security Profile + TRUST+ security profile required. Highest security requirments for incoming connection requests.
-
App Isolation
-
    -
  • - - None - Apps are not isolated. A malicious app may compromise the whole connector. - -
  • -
  • - - Containers - Apps run in separate containers but may still communicate with each other and the Internet. - -
  • - - Trusted Containers - Apps run in separate, signed and restricted containers. By default, they may only communicate with the Core Platform which enforces usage control policies. - -
-
-
-
- - - - - - -
-
-
-
Attestation Scope
-
    -
  • - - None - Integrity of the remote connector is not attested. There will be no guarantees about the software stack running on a remote connector. Any data sent to the remote connector must be considered unprotected. - -
  • -
  • - - Kernel & Core Platform - Integrity of the remote connector's kernel and Core Platform will be attested. These components will be guaranteed to be in a known state, but apps remain unattested. - -
  • - - Full Stack - Integrity of the remote connector's kernel, Core Platform, and apps will be attested. All these components will be guaranteed to be in a known state. - -
-
-
-
- - - - - - -
-
-
-
Data Usage Control
-
    -
  • - - None - Remote connector is not expected to provide usage control. - -
  • -
  • - - Compliance - Remote connector is expected to apply usage control policies, but not to strictly enforce them at a technical level. Legal usage obligations may still apply - -
  • - - Enforcement - Remote connector must be able to technically enforce usage control policies. This requires a trusted remote platform. - -
-
-
-
- - - - - - -
-
-
-
Audit Logging
-
    -
  • - - None - No audit logging. - -
  • -
  • - - Local - Local audit logging. - -
  • - - Remote Ledger - Non-repudiatable audit logging in a remote ledger. - -
-
-
-
- - - - - - -
-
-
-
Local data protection
-
    -
  • - - None - Data is stored without additional protection. Administrators or malicious users may be able to read/modify/delete stored data. - -
  • -
  • - - Secure data erasure - Locally stored data may be securely erased. Administrators or malicious users may still be able to read/modify/delete stored data. - -
  • - - Full Disk Encryption - Local data is stored on a full disk encryption (FDE) medium. - -
-
-
-
- - - - - - -
-
-
diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts index f6455eb84..7f146dd74 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts @@ -1,10 +1,3 @@ export interface Settings { - integrityProtectionAndVerification: string; - authentication: string; - serviceIsolation: string; - integrityProtectionVerificationScope: string; - appExecutionResources: string; - dataUsageControlSupport: string; - auditLogging: string; - localDataConfidentiality: string; + securityProfile: string; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index ea830f884..836d4ddcf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -259,15 +259,48 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } //toDo add further security attribute validation - if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) { - LOG.info("DAT is valid and secure"); - return validityTime; + + + if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements"); + } + return -1; + } + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements, TRUST LEVEL not reached"); + } + return -1; + } + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements, TRUST+ LEVEL not reached"); + } + return -1; + } } else { if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not fulfill the security requirements"); + LOG.warn("DAT does not fulfill the security requirements, not supported trust level"); } return -1; } + } else { //invalid security requirements format if (LOG.isWarnEnabled()) { @@ -284,34 +317,16 @@ public long verifyToken(byte[] dat, Object securityRequirements) { private SecurityRequirements parseSecurityRequirements(String dynamicAttrToken) { JSONObject asJson = new JSONObject(dynamicAttrToken); - if (!asJson.has("ids_attributes")) { - if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain ids_attributes"); - } - return null; - } - JSONObject idsAttributes = asJson.getJSONObject("ids_attributes"); - - if (!idsAttributes.has("security_profile")) { + if (!asJson.has("securityProfile")) { if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain security_profile"); + LOG.warn("DAT does not contain securityProfile"); } return null; } - JSONObject securityProfile = idsAttributes.getJSONObject("security_profile"); - - //check if all security requirements are available - if (!securityProfile.has("audit_logging")) { - if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain audit_logging"); - } - return null; - } - //toDo parse further security attributes - + //FIXME: Does this make sense? How are security requirements mapped? return new SecurityRequirements.Builder() - .setAuditLogging(securityProfile.getInt("audit_logging")) + .setRequiredSecurityLevel(asJson.getString("securityProfile")) .build(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java index 7e588989b..1cbe92d1f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -11,15 +11,15 @@ */ public class SecurityRequirements { - private int auditLogging; + private String securityLevel; public static class Builder { @NonNull private final SecurityRequirements requirements = new SecurityRequirements(); @NonNull - public Builder setAuditLogging(int auditLogging) { - this.requirements.auditLogging = auditLogging; + public Builder setRequiredSecurityLevel(String requiredSecurityLevel) { + this.requirements.securityLevel = requiredSecurityLevel; return this; } @@ -29,7 +29,7 @@ public SecurityRequirements build() { } } - public int getAuditLogging() { - return auditLogging; + public String getRequiredSecurityLevel() { + return securityLevel; } } diff --git a/karaf-assembly/src/main/resources/etc/settings.mapdb b/karaf-assembly/src/main/resources/etc/settings.mapdb index d2098f4a3bf0822e9f3344dd1de9e68b31263155..ad8f1bf13b1dfa14f3c2c16162b97dee06a38310 100644 GIT binary patch delta 568 zcmZo@Xkcsr;t3)$E;WBwGJt>przn_aVAukt6;4l_+}J42$;iMBlI4h)7~sgx2VydJ zY<|GnR<-#Zs|TyllZ#MY3{2`ENrvXh6%BSw9G@reXi#()01E{%fQ%MkPJ+-Zj~Ez1 zn)sO+z~(V+V&Dg>OJ7(Zun!DdVeEIJF zpt=o5O*}7@x_URY71>TDQ-2nv6T~8j}|Mv9L=a=u_O>6)L z%Sv^y4?uF0gk1{1fEX~a0L)(d1V1(ZZzzI*cZ^OsLAAHG@pHW9+ouAL~+(9dcZt zSZ>{R!w4`&aqJ{)HpSg-S{f&N(k>P=5(2dQry!6JAPIec^ap1&8l;g%nqf2&pxqwt zy(1y>A>r(9&)IWU=Unc+^S<}J&wcOvK6mb*P$(n{P~Ls=P<7j(w-ES~p6VBCL~>B9 z56=(0SJD0SUJ3Fzlz#Eo0}WMWhhcNi^?`=d2R;LvC7&Q-ecmtlWzaJzkP&|HbS0(Az(LB52E)K#-CTKucPFP zuNEC{es4lifj$KvmGmHD{b%3J)JMspzlYDi^m3+u_+>;2`$$oyE_)(dKbMgoIFjvW z^~xHv{pM`lDG{fBOpiPR?d)$Zu7Y*ty+20|h=v=%3c>F{F|r@_%TAQ^!uok0c^1}3 z^}Q9{{T1C3P>Mh)2Bid)Qc(7QQU*#nD0@NK2g+wac?^_40%iYrMfZWlu4BD##RxjS zM6&T^I`n}8QQk3G+>;BY=_RLie#Qc(+49q((i4)s8hjKRAJdGE4gR}Cn*3?0^o6Hx zzDKES^2?KPf#U5HNe2^(pXXBv(tO6k_{aIg)EY@@*PWTo#RWeNsEnFu zEw2Z{L?Y~NOrdvrLDaPZk8>7Ss# z$RoMOv#gNWn?YPRtj31b_^?_%tkw*xM~BtgVfEPEe8Yrwj_RKUsLcfT%X|tcf=N=Q zI77#&zGZ?*P5JdSt!ErNd6q$rRw^Io=$&*w9 zc{f6&2o*!bLn?>BgYdgeB!jfDz=lGgvs3&wkrcvIT%bt;8rrEa2zHNfC5RA8>Djoz zvy3Cjaez2>s(uJKgbMMru)fH%LM96)<3TsY)5`_zf0Sp?<`E8(zpbkD#yl!N4Brb9WwIFDDHJ*-JcXt7lAD@VCDrHa5TXnNRJYQ z`IRI>Vq9(w%RVuycgEmIcaH+4;@!#tC!b6RR1ii|#zWm$&z5x}l98U_7*cw*^8kvX z50J-RZ~8$~Wt&W1dEs2`^^OM*9-yE+cpyhU+uYvPCTo_rcUCsFUX?XhUg~VR*7jQa zC0S=>i%gCn-$%NTA~{m}nq1y-wc~ovqYP*59(;r~G-Iw8>-|juw{7#XDaHZE-TLWL ze$pB)U}Z8N#obvV(9M)~uh8I4N?_tGG`B%v1t-p@ty~Ha2`XrfBPdp2&PARIQp+Gg zgWDW%cWHx0x3j3KfGNmqkaoA}|7Ho~0Qv})-B{jl3)nV2lBcs4egD>dgY*4CdrTT^!y?ZIvqbWy(40f26922{{P*W|Cs+T^Xx zP0&Y;*E%}dJLNl(p*a^l4qbHN{NGg9ov%4l1%1?u_5ZiC6Ts`=4DWaWe>HTR`UXks@n1lFKZS||wwZ|L59-gZ?|Lulz^HAZ1u%6^>ydZ)z|i6 zZ|=q&={cOmDMVBN_pQyikL|#XX7V`?@W$r$j@^RcxeImQsH^{G zU0$pg8_(1?RQF?V6+*nhhv@cqUI6*6-63ZX*S0q|U4iidLgP|v3rw}9DzV&V^y`ly-F0jT_|`9@GJm$do#d7vD+x?{6TB8tmbO_m0c(R-OQ3t0)UOx z=U%NjQ+=_fvA$Mhfj2+pn@;%;PqemFws&5ZBQGCoZMoWXtm&G({j#j>7ed+JW++)xf5Mjn@kXCA z-woo_(T}JgsSSiD2n4YEnsF_z)nMf4G8I%Rhu|lk#GtcG`Vzbq zROIdhp@YrBK>i77=LC+dyqE~63XDx1uu(XRYuUnixdfBD|L(_hb1t((+ zM!Bcf18P4PFuLGS&Od93SQ)#+?Y6kQxW!<@-42J_?)TzT4%CVH=bSSxIM+IugCXN{ zTp$*l4yd(BU=RyvOwb4$oVBl7>4}uj!@!9mo8)T?F*_6ROh6lx!C7Y2?=X#-Voa1w zb2C1#-RAQ$iGbP=h1hLIODYhzGt{iOE>tv3rrFejhD?LSCIgze_<|Y?R?nn-YF#pD zbdLsS%@5mp?FtE=2aKYFFfwLHlA5U$8MjaSy>l3eTUejdgj;9;A`)8jMP|}gqa|YT z*wntXYt-oY-zLFHEMR6Ftd6F^Mln{ zrh(bWRMhIR$9$1VxY9HLx9azrX)BYU36DMPOLKE}gJs!<>8#GEd)hstb9ga>%WasO zvoUU$-3?@}HM5Dq5~i2|_v-;b6uL=m9&@R&Mz8eM{Q|t8p!mP2rvruo!k@{vu;jvQ z0Tf_j&S2G>fLpY*AMBgi=>i~Tv=*levpQC3zc;)JJOB(u;l63jPMa14J*hL9^gh9W z>GVFUYm_(BM!}OZ;5t6yikYTXQVV02xL-Fn7LGXx+)h|x=Eb1SN*U+INK9CP+Nj18 zN{!JjwOKDj=aWlB*ty_{W0N6$*c#G>!(Lk;I_e(<-)T*TsB;asE}1kI!{iLLIEPb# z`2@|aYg2OqjfZXN03Wv+>?W&zne>Eb4TjmpaeQS-ZR4kdsnBwA-fEhp6K38tvFfww z)+Ph@{Zt&a5t`u4ij$wS8cA|oPueHa^W3^VH8DNIQ2GQjzc^(w#PJ|GHtt_t;iJqd zA?R%>KWFqsbP+BY^CanImoQ08Bm=tSnsqYj;T;aUCBWGhP4huw)rKk`G4 From f4506a2e4bbea54098af14943596bbeca49bb241 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 099/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 6808ce21e..745d5c7b5 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -30,15 +30,15 @@ public void testValidToken() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(2) + .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") .build(); SecurityRequirements requirements2 = new SecurityRequirements.Builder() - .setAuditLogging(1) + .setRequiredSecurityLevel("idsc:BASE_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) >= 0); - assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements2) >= 0); + assertFalse(dapsDriver.verifyToken(token.getBytes(), requirements2) >= 0); } @Test From 92d7e85d89f98879d702a499663bd24a06dc8fc9 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 100/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 745d5c7b5..e0861325f 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(3) //token has supports only audit_logging 2 + .setRequiredSecurityLevel("\"idsc:TRUST+_SECURITY_PROFILE\"")() //token has supports only audit_logging 2 .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); @@ -201,7 +201,7 @@ public static void main(String[] args) { System.out.println(token); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(2) + .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") .build(); long ret; From da3512993020a329906787b67ea68206407b53ff Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 101/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index e0861325f..72b9f598b 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("\"idsc:TRUST+_SECURITY_PROFILE\"")() //token has supports only audit_logging 2 + .setRequiredSecurityLevel("idsc:TRUST+_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); From 35a3340e1806fc738757487f7502256977eb3b39 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Thu, 9 Jul 2020 10:02:00 +0200 Subject: [PATCH 102/237] Synched with info model --- .../ids/tokenmanager/TokenManagerService.java | 24 +++++++++---------- .../connection-configuration/configuration.ts | 2 +- .../connection-configuration.component.html | 6 ++--- .../daps/DefaultDapsDriver.java | 18 +++++++------- idscp2/src/test/java/DapsDriverTest.java | 8 +++---- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index a61a9c380..7a0de99f3 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -330,19 +330,19 @@ public void validateDATSecurityAttributes(Map claims, Connection //FIXME: Validate security profile the proper way ArrayList validTrustProfiles=new ArrayList(); - validTrustProfiles.add("idsc:TRUST_SECURITY_PROFILE"); - validTrustProfiles.add("idsc:BASE_SECURITY_PROFILE"); - validTrustProfiles.add("idsc:TRUST+_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:BASE_CONNECTOR_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE"); if (!validTrustProfiles.contains(securityProfile)) { throw new DatException("Client does not support valid trust profile."); } //TODO Check for trust profile - if(connectionSettings.getRequiredSecurityProfile().equals("idsc:BASE_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:BASE_SECURITY_PROFILE") - && !securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") - && !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + if(connectionSettings.getRequiredSecurityProfile().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " @@ -350,17 +350,17 @@ public void validateDATSecurityAttributes(Map claims, Connection + " given: " + securityProfile); } - } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") && - !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") && + !securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " + connectionSettings.getRequiredSecurityProfile() + " given: " + securityProfile); } - } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST+_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " + connectionSettings.getRequiredSecurityProfile() diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts index 68b8ae162..731992e41 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts @@ -11,7 +11,7 @@ export class Configuration { this.settings = settings; } else { this.settings = { - securityProfile: 'idsc:BASE_SECURITY_PROFILE' + securityProfile: 'idsc:BASE_CONNECTOR_SECURITY_PROFILE' }; } } diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html index e2886832b..237d95f37 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html @@ -56,17 +56,17 @@
Required Security Profile
+ [value]="'idsc:BASE_CONNECTOR_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:BASE_CONNECTOR_SECURITY_PROFILE'"/> + [value]="'idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE'"/> + [value]="'idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE'"/> diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 836d4ddcf..639a74488 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -261,10 +261,10 @@ public long verifyToken(byte[] dat, Object securityRequirements) { //toDo add further security attribute validation - if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { @@ -273,9 +273,9 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } return -1; } - } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { @@ -284,8 +284,8 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } return -1; } - } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 72b9f598b..27e88d723 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -30,11 +30,11 @@ public void testValidToken() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") .build(); SecurityRequirements requirements2 = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:BASE_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:BASE_CONNECTOR_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) >= 0); @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST+_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); @@ -201,7 +201,7 @@ public static void main(String[] args) { System.out.println(token); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") .build(); long ret; From 589b732093f27ebdce476f7b2a3e6ceb6ec46a66 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Thu, 9 Jul 2020 12:12:21 +0200 Subject: [PATCH 103/237] Fixed audience --- .../java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java | 2 +- .../drivers/default_driver_impl/daps/DefaultDapsDriver.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index 7a0de99f3..d940af467 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -102,7 +102,7 @@ public Map acquireToken( String connectorUUID) { String dynamicAttributeToken = "INVALID_TOKEN"; - String targetAudience = "IDS_Connector"; + String targetAudience = "idsc:IDS_CONNECTORS_ALL"; Map jwtClaims = null; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 639a74488..820e6700f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -46,7 +46,7 @@ public class DefaultDapsDriver implements DapsDriver { private final Key privateKey; //private key can be reused private final String connectorUUID; private final String dapsUrl; - private final String targetAudience = "IDS_Connector"; + private final String targetAudience = "idsc:IDS_CONNECTORS_ALL"; public DefaultDapsDriver(DefaultDapsDriverConfig config) { From 5315043164f02683274328a72194fc3270b050a8 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Tue, 14 Jul 2020 15:26:01 +0200 Subject: [PATCH 104/237] Automatically generate connector uuid (client id) from AKI and SKI. Remove connector uuid from db and configuration options since obsolete. --- .../idscp2/client/Idscp2ClientEndpoint.kt | 1 - .../camel/idscp2/server/CamelIdscp2Server.kt | 1 - .../ids/api/settings/ConnectorConfig.java | 7 +- .../aisec/ids/api/tokenm/TokenManager.java | 3 +- ids-token-manager/build.gradle | 1 + .../ids/tokenmanager/TokenManagerService.java | 93 ++++++++++++++--- .../aisec/ids/webconsole/api/ConfigApi.java | 3 +- .../www/src/app/ids/ids.component.html | 7 -- .../www/src/app/ids/ids.component.ts | 3 +- .../www/src/app/ids/settings.interface.ts | 1 - .../daps/DefaultDapsDriver.java | 97 +++++++++++++++++- .../daps/DefaultDapsDriverConfig.java | 12 --- .../keystores/PreConfiguration.java | 34 ++++++ .../idscp2/example/Idscp2ClientInitiator.java | 1 - .../idscp2/example/Idscp2ServerInitiator.java | 1 - idscp2/src/test/java/DapsDriverTest.java | 16 +-- .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes libraryVersions.yaml | 1 + 18 files changed, 218 insertions(+), 64 deletions(-) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt index 675a44fc3..7a212bb69 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt @@ -121,7 +121,6 @@ class Idscp2ClientEndpoint(uri: String?, private val remaining: String, componen } clientSettings = clientSettingsBuilder.build() dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID(settings.connectorConfig.connectorUUID) .setDapsUrl(settings.connectorConfig.dapsUrl) .setKeyAlias(clientSettings.dapsKeyAlias) .setKeyStorePath(clientSettings.keyStorePath) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt index b14e51298..ccd159c5b 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt @@ -33,7 +33,6 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener init { val dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID(Idscp2OsgiComponent.getSettings().connectorConfig.connectorUUID) .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) .setKeyAlias(serverSettings.dapsKeyAlias) .setKeyStorePath(serverSettings.keyStorePath) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java index a373bc7c8..18b754efb 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java @@ -37,7 +37,6 @@ public final class ConnectorConfig implements Serializable { private final String keystorePassword; private final String keystoreAliasName; private final String truststoreName; - private final String connectorUUID; public ConnectorConfig() { appstoreUrl = @@ -49,12 +48,11 @@ public ConnectorConfig() { acmeDnsWebcon = ""; acmePortWebcon = 80; tosAcceptWebcon = false; - dapsUrl = "http://daps.aisec.fraunhofer.de/token"; + dapsUrl = "https://daps.aisec.fraunhofer.de"; keystoreName = "client-keystore.jks"; keystorePassword = "password"; keystoreAliasName = "1"; truststoreName = "client-truststore.jks"; - connectorUUID = "00c6155a-966d-4d2c-af6e-60f997e24da2"; } public String getAppstoreUrl() { @@ -109,7 +107,4 @@ public String getTruststoreName() { return truststoreName; } - public String getConnectorUUID() { - return connectorUUID; - } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java index 5c3d45c0d..abf1a6a3c 100755 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java @@ -40,8 +40,7 @@ Map acquireToken( String keyStoreName, String keyStorePassword, String keystoreAliasName, - String trustStoreName, - String connectorUUID); + String trustStoreName); Map verifyJWT( String dynamicAttributeToken, diff --git a/ids-token-manager/build.gradle b/ids-token-manager/build.gradle index dfcd54352..2b852b204 100755 --- a/ids-token-manager/build.gradle +++ b/ids-token-manager/build.gradle @@ -10,6 +10,7 @@ dependencies { providedByBundle group: 'com.squareup.okio', name: 'okio', version: libraryVersions.okio providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: libraryVersions.jose4j providedByBundle group: 'org.json', name: 'json', version: libraryVersions.orgJson + providedByBundle group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: libraryVersions.bouncycastle testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index d940af467..183255e00 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -29,6 +29,11 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import okhttp3.*; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.jose4j.http.Get; import org.jose4j.jwk.HttpsJwks; import org.jose4j.jws.AlgorithmIdentifiers; @@ -82,14 +87,12 @@ public class TokenManagerService implements TokenManager { * (DAPS) * * @param targetDirectory The directory the keystore resides in - * @param dapsUrl The token aquiry URL (e.g., http://daps.aisec.fraunhofer.de/token + * @param dapsUrl The token aquiry URL (e.g., http://daps.aisec.fraunhofer.de * @param keyStoreName Name of the keystore file (e.g., server-keystore.jks) * @param keyStorePassword Password of keystore * @param keystoreAliasName Alias of the connector's key entry. For default keystores with only * one entry, this is '1' * @param trustStoreName Name of the truststore file - * @param connectorUUID The UUID used to register the connector at the DAPS. Should be replaced by - * working code that does this automatically */ @Override public Map acquireToken( @@ -98,8 +101,7 @@ public Map acquireToken( String keyStoreName, String keyStorePassword, String keystoreAliasName, - String trustStoreName, - String connectorUUID) { + String trustStoreName) { String dynamicAttributeToken = "INVALID_TOKEN"; String targetAudience = "idsc:IDS_CONNECTORS_ALL"; @@ -151,13 +153,26 @@ public Map acquireToken( throw new RuntimeException(e); } - LOG.info("\tCertificate Subject: " + cert.getSubjectDN()); + // Get AKI //GET 2.5.29.14 SubjectKeyIdentifier / 2.5.29.35 AuthorityKeyIdentifier - String authorityKeyIndentifier = new String (cert.getExtensionValue("2.5.29.35")); - String subjectKeyIdenfier = new String (cert.getExtensionValue("2.5.29.14")); - LOG.info("AKI: " + authorityKeyIndentifier); - LOG.info("SKI: " + subjectKeyIdenfier); - //connectorUUID = subjectKeyIdenfier + ":" + authorityKeyIndentifier.substring(0, authorityKeyIndentifier.length() - 1); + String aki_oid = Extension.authorityKeyIdentifier.getId(); + byte[] rawAuthorityKeyIdentifier = cert.getExtensionValue(aki_oid); + ASN1OctetString akiOc = ASN1OctetString.getInstance(rawAuthorityKeyIdentifier); + AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiOc.getOctets()); + byte[] authorityKeyIdentifier = aki.getKeyIdentifier(); + + //GET SKI + String ski_oid = Extension.subjectKeyIdentifier.getId(); + byte[] rawSubjectKeyIdentifier = cert.getExtensionValue(ski_oid); + ASN1OctetString ski0c = ASN1OctetString.getInstance(rawSubjectKeyIdentifier); + SubjectKeyIdentifier ski = SubjectKeyIdentifier.getInstance(ski0c.getOctets()); + byte[] subjectKeyIdentifier = ski.getKeyIdentifier(); + + String aki_result = beatifyHex(encodeHexString(authorityKeyIdentifier).toUpperCase()); + String ski_result = beatifyHex(encodeHexString(subjectKeyIdentifier).toUpperCase()); + + String connectorUUID = ski_result + "keyid:" + aki_result.substring(0, aki_result.length() - 1); + LOG.info("ConnectorUUID: " + connectorUUID); LOG.info("Retrieving Dynamic Attribute Token..."); @@ -381,6 +396,59 @@ public void validateDATSecurityAttributes(Map claims, Connection } } + /*** + * Split string ever len chars and return string array + * @param src + * @param len + * @return + */ + public static String[] split(String src, int len) { + String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)]; + for (int i=0; i> 4) & 0xF, 16); + hexDigits[1] = Character.forDigit((num & 0xF), 16); + return new String(hexDigits); + } + + /** + * Encode a byte array to an hex string + * @param byteArray + * @return + */ + private String encodeHexString(byte[] byteArray) { + StringBuffer hexStringBuffer = new StringBuffer(); + for (int i = 0; i < byteArray.length; i++) { + hexStringBuffer.append(byteToHex(byteArray[i])); + } + return hexStringBuffer.toString(); + } + @Activate public void run() { LOG.info("Token renewal triggered."); @@ -392,8 +460,7 @@ public void run() { config.getKeystoreName(), config.getKeystorePassword(), config.getKeystoreAliasName(), - config.getTruststoreName(), - config.getConnectorUUID()); + config.getTruststoreName()); } catch (Exception e) { LOG.error("Token renewal failed", e); diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java index 40cdbc205..6fad55564 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java @@ -106,8 +106,7 @@ public String set(ConnectorConfig config) { config.getKeystoreName(), config.getKeystorePassword(), config.getKeystoreAliasName(), - config.getTruststoreName(), - config.getConnectorUUID()); + config.getTruststoreName()); } catch (Exception e) { e.printStackTrace(); } diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html b/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html index 1650937a8..dfd31343f 100644 --- a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html +++ b/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html @@ -116,13 +116,6 @@

Settings

Valid truststore name required -
- - - Valid UUID required -
-
diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts index f6455eb84..7f146dd74 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/settings.interface.ts @@ -1,10 +1,3 @@ export interface Settings { - integrityProtectionAndVerification: string; - authentication: string; - serviceIsolation: string; - integrityProtectionVerificationScope: string; - appExecutionResources: string; - dataUsageControlSupport: string; - auditLogging: string; - localDataConfidentiality: string; + securityProfile: string; } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index ea830f884..836d4ddcf 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -259,15 +259,48 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } //toDo add further security attribute validation - if (secRequirements.getAuditLogging() <= providedSecurityProfile.getAuditLogging()) { - LOG.info("DAT is valid and secure"); - return validityTime; + + + if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements"); + } + return -1; + } + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements, TRUST LEVEL not reached"); + } + return -1; + } + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + LOG.info("DAT is valid and secure"); + return validityTime; + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("DAT does not fulfill the security requirements, TRUST+ LEVEL not reached"); + } + return -1; + } } else { if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not fulfill the security requirements"); + LOG.warn("DAT does not fulfill the security requirements, not supported trust level"); } return -1; } + } else { //invalid security requirements format if (LOG.isWarnEnabled()) { @@ -284,34 +317,16 @@ public long verifyToken(byte[] dat, Object securityRequirements) { private SecurityRequirements parseSecurityRequirements(String dynamicAttrToken) { JSONObject asJson = new JSONObject(dynamicAttrToken); - if (!asJson.has("ids_attributes")) { - if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain ids_attributes"); - } - return null; - } - JSONObject idsAttributes = asJson.getJSONObject("ids_attributes"); - - if (!idsAttributes.has("security_profile")) { + if (!asJson.has("securityProfile")) { if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain security_profile"); + LOG.warn("DAT does not contain securityProfile"); } return null; } - JSONObject securityProfile = idsAttributes.getJSONObject("security_profile"); - - //check if all security requirements are available - if (!securityProfile.has("audit_logging")) { - if (LOG.isWarnEnabled()) { - LOG.warn("DAT does not contain audit_logging"); - } - return null; - } - //toDo parse further security attributes - + //FIXME: Does this make sense? How are security requirements mapped? return new SecurityRequirements.Builder() - .setAuditLogging(securityProfile.getInt("audit_logging")) + .setRequiredSecurityLevel(asJson.getString("securityProfile")) .build(); } } diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java index 7e588989b..1cbe92d1f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/SecurityRequirements.java @@ -11,15 +11,15 @@ */ public class SecurityRequirements { - private int auditLogging; + private String securityLevel; public static class Builder { @NonNull private final SecurityRequirements requirements = new SecurityRequirements(); @NonNull - public Builder setAuditLogging(int auditLogging) { - this.requirements.auditLogging = auditLogging; + public Builder setRequiredSecurityLevel(String requiredSecurityLevel) { + this.requirements.securityLevel = requiredSecurityLevel; return this; } @@ -29,7 +29,7 @@ public SecurityRequirements build() { } } - public int getAuditLogging() { - return auditLogging; + public String getRequiredSecurityLevel() { + return securityLevel; } } diff --git a/karaf-assembly/src/main/resources/etc/settings.mapdb b/karaf-assembly/src/main/resources/etc/settings.mapdb index d2098f4a3bf0822e9f3344dd1de9e68b31263155..ad8f1bf13b1dfa14f3c2c16162b97dee06a38310 100644 GIT binary patch delta 568 zcmZo@Xkcsr;t3)$E;WBwGJt>przn_aVAukt6;4l_+}J42$;iMBlI4h)7~sgx2VydJ zY<|GnR<-#Zs|TyllZ#MY3{2`ENrvXh6%BSw9G@reXi#()01E{%fQ%MkPJ+-Zj~Ez1 zn)sO+z~(V+V&Dg>OJ7(Zun!DdVeEIJF zpt=o5O*}7@x_URY71>TDQ-2nv6T~8j}|Mv9L=a=u_O>6)L z%Sv^y4?uF0gk1{1fEX~a0L)(d1V1(ZZzzI*cZ^OsLAAHG@pHW9+ouAL~+(9dcZt zSZ>{R!w4`&aqJ{)HpSg-S{f&N(k>P=5(2dQry!6JAPIec^ap1&8l;g%nqf2&pxqwt zy(1y>A>r(9&)IWU=Unc+^S<}J&wcOvK6mb*P$(n{P~Ls=P<7j(w-ES~p6VBCL~>B9 z56=(0SJD0SUJ3Fzlz#Eo0}WMWhhcNi^?`=d2R;LvC7&Q-ecmtlWzaJzkP&|HbS0(Az(LB52E)K#-CTKucPFP zuNEC{es4lifj$KvmGmHD{b%3J)JMspzlYDi^m3+u_+>;2`$$oyE_)(dKbMgoIFjvW z^~xHv{pM`lDG{fBOpiPR?d)$Zu7Y*ty+20|h=v=%3c>F{F|r@_%TAQ^!uok0c^1}3 z^}Q9{{T1C3P>Mh)2Bid)Qc(7QQU*#nD0@NK2g+wac?^_40%iYrMfZWlu4BD##RxjS zM6&T^I`n}8QQk3G+>;BY=_RLie#Qc(+49q((i4)s8hjKRAJdGE4gR}Cn*3?0^o6Hx zzDKES^2?KPf#U5HNe2^(pXXBv(tO6k_{aIg)EY@@*PWTo#RWeNsEnFu zEw2Z{L?Y~NOrdvrLDaPZk8>7Ss# z$RoMOv#gNWn?YPRtj31b_^?_%tkw*xM~BtgVfEPEe8Yrwj_RKUsLcfT%X|tcf=N=Q zI77#&zGZ?*P5JdSt!ErNd6q$rRw^Io=$&*w9 zc{f6&2o*!bLn?>BgYdgeB!jfDz=lGgvs3&wkrcvIT%bt;8rrEa2zHNfC5RA8>Djoz zvy3Cjaez2>s(uJKgbMMru)fH%LM96)<3TsY)5`_zf0Sp?<`E8(zpbkD#yl!N4Brb9WwIFDDHJ*-JcXt7lAD@VCDrHa5TXnNRJYQ z`IRI>Vq9(w%RVuycgEmIcaH+4;@!#tC!b6RR1ii|#zWm$&z5x}l98U_7*cw*^8kvX z50J-RZ~8$~Wt&W1dEs2`^^OM*9-yE+cpyhU+uYvPCTo_rcUCsFUX?XhUg~VR*7jQa zC0S=>i%gCn-$%NTA~{m}nq1y-wc~ovqYP*59(;r~G-Iw8>-|juw{7#XDaHZE-TLWL ze$pB)U}Z8N#obvV(9M)~uh8I4N?_tGG`B%v1t-p@ty~Ha2`XrfBPdp2&PARIQp+Gg zgWDW%cWHx0x3j3KfGNmqkaoA}|7Ho~0Qv})-B{jl3)nV2lBcs4egD>dgY*4CdrTT^!y?ZIvqbWy(40f26922{{P*W|Cs+T^Xx zP0&Y;*E%}dJLNl(p*a^l4qbHN{NGg9ov%4l1%1?u_5ZiC6Ts`=4DWaWe>HTR`UXks@n1lFKZS||wwZ|L59-gZ?|Lulz^HAZ1u%6^>ydZ)z|i6 zZ|=q&={cOmDMVBN_pQyikL|#XX7V`?@W$r$j@^RcxeImQsH^{G zU0$pg8_(1?RQF?V6+*nhhv@cqUI6*6-63ZX*S0q|U4iidLgP|v3rw}9DzV&V^y`ly-F0jT_|`9@GJm$do#d7vD+x?{6TB8tmbO_m0c(R-OQ3t0)UOx z=U%NjQ+=_fvA$Mhfj2+pn@;%;PqemFws&5ZBQGCoZMoWXtm&G({j#j>7ed+JW++)xf5Mjn@kXCA z-woo_(T}JgsSSiD2n4YEnsF_z)nMf4G8I%Rhu|lk#GtcG`Vzbq zROIdhp@YrBK>i77=LC+dyqE~63XDx1uu(XRYuUnixdfBD|L(_hb1t((+ zM!Bcf18P4PFuLGS&Od93SQ)#+?Y6kQxW!<@-42J_?)TzT4%CVH=bSSxIM+IugCXN{ zTp$*l4yd(BU=RyvOwb4$oVBl7>4}uj!@!9mo8)T?F*_6ROh6lx!C7Y2?=X#-Voa1w zb2C1#-RAQ$iGbP=h1hLIODYhzGt{iOE>tv3rrFejhD?LSCIgze_<|Y?R?nn-YF#pD zbdLsS%@5mp?FtE=2aKYFFfwLHlA5U$8MjaSy>l3eTUejdgj;9;A`)8jMP|}gqa|YT z*wntXYt-oY-zLFHEMR6Ftd6F^Mln{ zrh(bWRMhIR$9$1VxY9HLx9azrX)BYU36DMPOLKE}gJs!<>8#GEd)hstb9ga>%WasO zvoUU$-3?@}HM5Dq5~i2|_v-;b6uL=m9&@R&Mz8eM{Q|t8p!mP2rvruo!k@{vu;jvQ z0Tf_j&S2G>fLpY*AMBgi=>i~Tv=*levpQC3zc;)JJOB(u;l63jPMa14J*hL9^gh9W z>GVFUYm_(BM!}OZ;5t6yikYTXQVV02xL-Fn7LGXx+)h|x=Eb1SN*U+INK9CP+Nj18 zN{!JjwOKDj=aWlB*ty_{W0N6$*c#G>!(Lk;I_e(<-)T*TsB;asE}1kI!{iLLIEPb# z`2@|aYg2OqjfZXN03Wv+>?W&zne>Eb4TjmpaeQS-ZR4kdsnBwA-fEhp6K38tvFfww z)+Ph@{Zt&a5t`u4ij$wS8cA|oPueHa^W3^VH8DNIQ2GQjzc^(w#PJ|GHtt_t;iJqd zA?R%>KWFqsbP+BY^CanImoQ08Bm=tSnsqYj;T;aUCBWGhP4huw)rKk`G4 From 53ddb5113e3be19c5818ef4df7500e0263f26987 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 119/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 6808ce21e..745d5c7b5 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -30,15 +30,15 @@ public void testValidToken() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(2) + .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") .build(); SecurityRequirements requirements2 = new SecurityRequirements.Builder() - .setAuditLogging(1) + .setRequiredSecurityLevel("idsc:BASE_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) >= 0); - assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements2) >= 0); + assertFalse(dapsDriver.verifyToken(token.getBytes(), requirements2) >= 0); } @Test From 00eb2467117228721fb6ff3f79f8c785e6ad0d01 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 120/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 745d5c7b5..e0861325f 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(3) //token has supports only audit_logging 2 + .setRequiredSecurityLevel("\"idsc:TRUST+_SECURITY_PROFILE\"")() //token has supports only audit_logging 2 .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); @@ -201,7 +201,7 @@ public static void main(String[] args) { System.out.println(token); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setAuditLogging(2) + .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") .build(); long ret; From 9e617131f662b94cc7af19dd8f9518563e8bd3db Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Wed, 8 Jul 2020 12:04:32 +0200 Subject: [PATCH 121/237] upgraded to DAPSv2 --- idscp2/src/test/java/DapsDriverTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index e0861325f..72b9f598b 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("\"idsc:TRUST+_SECURITY_PROFILE\"")() //token has supports only audit_logging 2 + .setRequiredSecurityLevel("idsc:TRUST+_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); From be1cbb9dbf58598161b41a9d50fe3d3972d6bb42 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Thu, 9 Jul 2020 10:02:00 +0200 Subject: [PATCH 122/237] Synched with info model --- .../ids/tokenmanager/TokenManagerService.java | 24 +++++++++---------- .../connection-configuration/configuration.ts | 2 +- .../connection-configuration.component.html | 6 ++--- .../daps/DefaultDapsDriver.java | 18 +++++++------- idscp2/src/test/java/DapsDriverTest.java | 8 +++---- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index a61a9c380..7a0de99f3 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -330,19 +330,19 @@ public void validateDATSecurityAttributes(Map claims, Connection //FIXME: Validate security profile the proper way ArrayList validTrustProfiles=new ArrayList(); - validTrustProfiles.add("idsc:TRUST_SECURITY_PROFILE"); - validTrustProfiles.add("idsc:BASE_SECURITY_PROFILE"); - validTrustProfiles.add("idsc:TRUST+_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:BASE_CONNECTOR_SECURITY_PROFILE"); + validTrustProfiles.add("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE"); if (!validTrustProfiles.contains(securityProfile)) { throw new DatException("Client does not support valid trust profile."); } //TODO Check for trust profile - if(connectionSettings.getRequiredSecurityProfile().equals("idsc:BASE_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:BASE_SECURITY_PROFILE") - && !securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") - && !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + if(connectionSettings.getRequiredSecurityProfile().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") + && !securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " @@ -350,17 +350,17 @@ public void validateDATSecurityAttributes(Map claims, Connection + " given: " + securityProfile); } - } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:TRUST_SECURITY_PROFILE") && - !securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") && + !securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " + connectionSettings.getRequiredSecurityProfile() + " given: " + securityProfile); } - } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUST+_SECURITY_PROFILE")) { - if (!securityProfile.equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(connectionSettings.getRequiredSecurityProfile().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { + if (!securityProfile.equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { throw new DatException( "Client does not support required trust profile: Required: " + connectionSettings.getRequiredSecurityProfile() diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts index 68b8ae162..731992e41 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/configuration.ts @@ -11,7 +11,7 @@ export class Configuration { this.settings = settings; } else { this.settings = { - securityProfile: 'idsc:BASE_SECURITY_PROFILE' + securityProfile: 'idsc:BASE_CONNECTOR_SECURITY_PROFILE' }; } } diff --git a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html index e2886832b..237d95f37 100644 --- a/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html +++ b/ids-webconsole/src/main/resources/www/src/app/connection-configuration/connection-configuration.component.html @@ -56,17 +56,17 @@
Required Security Profile
+ [value]="'idsc:BASE_CONNECTOR_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:BASE_CONNECTOR_SECURITY_PROFILE'"/> + [value]="'idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE'"/> + [value]="'idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE'" [checked]="model.settings.securityProfile === 'idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE'"/> diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 836d4ddcf..639a74488 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -261,10 +261,10 @@ public long verifyToken(byte[] dat, Object securityRequirements) { //toDo add further security attribute validation - if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + if(secRequirements.getRequiredSecurityLevel().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:BASE_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { @@ -273,9 +273,9 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } return -1; } - } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST_SECURITY_PROFILE") || - providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") || + providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { @@ -284,8 +284,8 @@ public long verifyToken(byte[] dat, Object securityRequirements) { } return -1; } - } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { - if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUST+_SECURITY_PROFILE")) { + } else if(secRequirements.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { + if (providedSecurityProfile.getRequiredSecurityLevel().equals("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE")) { LOG.info("DAT is valid and secure"); return validityTime; } else { diff --git a/idscp2/src/test/java/DapsDriverTest.java b/idscp2/src/test/java/DapsDriverTest.java index 72b9f598b..27e88d723 100644 --- a/idscp2/src/test/java/DapsDriverTest.java +++ b/idscp2/src/test/java/DapsDriverTest.java @@ -30,11 +30,11 @@ public void testValidToken() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") .build(); SecurityRequirements requirements2 = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:BASE_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:BASE_CONNECTOR_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) >= 0); @@ -175,7 +175,7 @@ public void testInvalidAuditLogging() { assertNotEquals(token, "INVALID_TOKEN"); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST+_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_PLUS_SECURITY_PROFILE") .build(); assertTrue(dapsDriver.verifyToken(token.getBytes(), requirements) < 0); @@ -201,7 +201,7 @@ public static void main(String[] args) { System.out.println(token); SecurityRequirements requirements = new SecurityRequirements.Builder() - .setRequiredSecurityLevel("idsc:TRUST_SECURITY_PROFILE") + .setRequiredSecurityLevel("idsc:TRUSTED_CONNECTOR_SECURITY_PROFILE") .build(); long ret; From 5064bd311557a7e809af88ad35616e47836c1e85 Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Thu, 9 Jul 2020 12:12:21 +0200 Subject: [PATCH 123/237] Fixed audience --- .../java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java | 2 +- .../drivers/default_driver_impl/daps/DefaultDapsDriver.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index 7a0de99f3..d940af467 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -102,7 +102,7 @@ public Map acquireToken( String connectorUUID) { String dynamicAttributeToken = "INVALID_TOKEN"; - String targetAudience = "IDS_Connector"; + String targetAudience = "idsc:IDS_CONNECTORS_ALL"; Map jwtClaims = null; diff --git a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java index 639a74488..820e6700f 100644 --- a/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java +++ b/idscp2/src/main/java/de/fhg/aisec/ids/idscp2/drivers/default_driver_impl/daps/DefaultDapsDriver.java @@ -46,7 +46,7 @@ public class DefaultDapsDriver implements DapsDriver { private final Key privateKey; //private key can be reused private final String connectorUUID; private final String dapsUrl; - private final String targetAudience = "IDS_Connector"; + private final String targetAudience = "idsc:IDS_CONNECTORS_ALL"; public DefaultDapsDriver(DefaultDapsDriverConfig config) { From ca7debb04e4bfcbb31a405cf977ab5e0988b8fde Mon Sep 17 00:00:00 2001 From: Gerd Brost Date: Tue, 14 Jul 2020 15:26:01 +0200 Subject: [PATCH 124/237] Automatically generate connector uuid (client id) from AKI and SKI. Remove connector uuid from db and configuration options since obsolete. --- .../idscp2/client/Idscp2ClientEndpoint.kt | 1 - .../camel/idscp2/server/CamelIdscp2Server.kt | 1 - .../ids/api/settings/ConnectorConfig.java | 7 +- .../aisec/ids/api/tokenm/TokenManager.java | 3 +- ids-token-manager/build.gradle | 1 + .../ids/tokenmanager/TokenManagerService.java | 93 ++++++++++++++--- .../aisec/ids/webconsole/api/ConfigApi.java | 3 +- .../www/src/app/ids/ids.component.html | 7 -- .../www/src/app/ids/ids.component.ts | 3 +- .../www/src/app/ids/settings.interface.ts | 1 - .../daps/DefaultDapsDriver.java | 97 +++++++++++++++++- .../daps/DefaultDapsDriverConfig.java | 12 --- .../keystores/PreConfiguration.java | 34 ++++++ .../idscp2/example/Idscp2ClientInitiator.java | 1 - .../idscp2/example/Idscp2ServerInitiator.java | 1 - idscp2/src/test/java/DapsDriverTest.java | 16 +-- .../src/main/resources/etc/settings.mapdb | Bin 2097152 -> 2097152 bytes libraryVersions.yaml | 1 + 18 files changed, 218 insertions(+), 64 deletions(-) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt index 675a44fc3..7a212bb69 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/client/Idscp2ClientEndpoint.kt @@ -121,7 +121,6 @@ class Idscp2ClientEndpoint(uri: String?, private val remaining: String, componen } clientSettings = clientSettingsBuilder.build() dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID(settings.connectorConfig.connectorUUID) .setDapsUrl(settings.connectorConfig.dapsUrl) .setKeyAlias(clientSettings.dapsKeyAlias) .setKeyStorePath(clientSettings.keyStorePath) diff --git a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt index b14e51298..ccd159c5b 100644 --- a/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt +++ b/camel-idscp2/src/main/kotlin/de/fhg/aisec/ids/camel/idscp2/server/CamelIdscp2Server.kt @@ -33,7 +33,6 @@ class CamelIdscp2Server(serverSettings: Idscp2Settings) : Idscp2EndpointListener init { val dapsDriverConfig = DefaultDapsDriverConfig.Builder() - .setConnectorUUID(Idscp2OsgiComponent.getSettings().connectorConfig.connectorUUID) .setDapsUrl(Idscp2OsgiComponent.getSettings().connectorConfig.dapsUrl) .setKeyAlias(serverSettings.dapsKeyAlias) .setKeyStorePath(serverSettings.keyStorePath) diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java index a373bc7c8..18b754efb 100644 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/settings/ConnectorConfig.java @@ -37,7 +37,6 @@ public final class ConnectorConfig implements Serializable { private final String keystorePassword; private final String keystoreAliasName; private final String truststoreName; - private final String connectorUUID; public ConnectorConfig() { appstoreUrl = @@ -49,12 +48,11 @@ public ConnectorConfig() { acmeDnsWebcon = ""; acmePortWebcon = 80; tosAcceptWebcon = false; - dapsUrl = "http://daps.aisec.fraunhofer.de/token"; + dapsUrl = "https://daps.aisec.fraunhofer.de"; keystoreName = "client-keystore.jks"; keystorePassword = "password"; keystoreAliasName = "1"; truststoreName = "client-truststore.jks"; - connectorUUID = "00c6155a-966d-4d2c-af6e-60f997e24da2"; } public String getAppstoreUrl() { @@ -109,7 +107,4 @@ public String getTruststoreName() { return truststoreName; } - public String getConnectorUUID() { - return connectorUUID; - } } diff --git a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java index 5c3d45c0d..abf1a6a3c 100755 --- a/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java +++ b/ids-api/src/main/java/de/fhg/aisec/ids/api/tokenm/TokenManager.java @@ -40,8 +40,7 @@ Map acquireToken( String keyStoreName, String keyStorePassword, String keystoreAliasName, - String trustStoreName, - String connectorUUID); + String trustStoreName); Map verifyJWT( String dynamicAttributeToken, diff --git a/ids-token-manager/build.gradle b/ids-token-manager/build.gradle index dfcd54352..2b852b204 100755 --- a/ids-token-manager/build.gradle +++ b/ids-token-manager/build.gradle @@ -10,6 +10,7 @@ dependencies { providedByBundle group: 'com.squareup.okio', name: 'okio', version: libraryVersions.okio providedByBundle group: 'org.bitbucket.b_c', name: 'jose4j', version: libraryVersions.jose4j providedByBundle group: 'org.json', name: 'json', version: libraryVersions.orgJson + providedByBundle group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: libraryVersions.bouncycastle testImplementation group: 'junit', name: 'junit', version: libraryVersions.junit4 testImplementation group: 'org.mockito', name: 'mockito-core', version: libraryVersions.mockito diff --git a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java index d940af467..183255e00 100755 --- a/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java +++ b/ids-token-manager/src/main/java/de/fhg/aisec/ids/tokenmanager/TokenManagerService.java @@ -29,6 +29,11 @@ import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import okhttp3.*; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.DEROctetString; +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.jose4j.http.Get; import org.jose4j.jwk.HttpsJwks; import org.jose4j.jws.AlgorithmIdentifiers; @@ -82,14 +87,12 @@ public class TokenManagerService implements TokenManager { * (DAPS) * * @param targetDirectory The directory the keystore resides in - * @param dapsUrl The token aquiry URL (e.g., http://daps.aisec.fraunhofer.de/token + * @param dapsUrl The token aquiry URL (e.g., http://daps.aisec.fraunhofer.de * @param keyStoreName Name of the keystore file (e.g., server-keystore.jks) * @param keyStorePassword Password of keystore * @param keystoreAliasName Alias of the connector's key entry. For default keystores with only * one entry, this is '1' * @param trustStoreName Name of the truststore file - * @param connectorUUID The UUID used to register the connector at the DAPS. Should be replaced by - * working code that does this automatically */ @Override public Map acquireToken( @@ -98,8 +101,7 @@ public Map acquireToken( String keyStoreName, String keyStorePassword, String keystoreAliasName, - String trustStoreName, - String connectorUUID) { + String trustStoreName) { String dynamicAttributeToken = "INVALID_TOKEN"; String targetAudience = "idsc:IDS_CONNECTORS_ALL"; @@ -151,13 +153,26 @@ public Map acquireToken( throw new RuntimeException(e); } - LOG.info("\tCertificate Subject: " + cert.getSubjectDN()); + // Get AKI //GET 2.5.29.14 SubjectKeyIdentifier / 2.5.29.35 AuthorityKeyIdentifier - String authorityKeyIndentifier = new String (cert.getExtensionValue("2.5.29.35")); - String subjectKeyIdenfier = new String (cert.getExtensionValue("2.5.29.14")); - LOG.info("AKI: " + authorityKeyIndentifier); - LOG.info("SKI: " + subjectKeyIdenfier); - //connectorUUID = subjectKeyIdenfier + ":" + authorityKeyIndentifier.substring(0, authorityKeyIndentifier.length() - 1); + String aki_oid = Extension.authorityKeyIdentifier.getId(); + byte[] rawAuthorityKeyIdentifier = cert.getExtensionValue(aki_oid); + ASN1OctetString akiOc = ASN1OctetString.getInstance(rawAuthorityKeyIdentifier); + AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(akiOc.getOctets()); + byte[] authorityKeyIdentifier = aki.getKeyIdentifier(); + + //GET SKI + String ski_oid = Extension.subjectKeyIdentifier.getId(); + byte[] rawSubjectKeyIdentifier = cert.getExtensionValue(ski_oid); + ASN1OctetString ski0c = ASN1OctetString.getInstance(rawSubjectKeyIdentifier); + SubjectKeyIdentifier ski = SubjectKeyIdentifier.getInstance(ski0c.getOctets()); + byte[] subjectKeyIdentifier = ski.getKeyIdentifier(); + + String aki_result = beatifyHex(encodeHexString(authorityKeyIdentifier).toUpperCase()); + String ski_result = beatifyHex(encodeHexString(subjectKeyIdentifier).toUpperCase()); + + String connectorUUID = ski_result + "keyid:" + aki_result.substring(0, aki_result.length() - 1); + LOG.info("ConnectorUUID: " + connectorUUID); LOG.info("Retrieving Dynamic Attribute Token..."); @@ -381,6 +396,59 @@ public void validateDATSecurityAttributes(Map claims, Connection } } + /*** + * Split string ever len chars and return string array + * @param src + * @param len + * @return + */ + public static String[] split(String src, int len) { + String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)]; + for (int i=0; i> 4) & 0xF, 16); + hexDigits[1] = Character.forDigit((num & 0xF), 16); + return new String(hexDigits); + } + + /** + * Encode a byte array to an hex string + * @param byteArray + * @return + */ + private String encodeHexString(byte[] byteArray) { + StringBuffer hexStringBuffer = new StringBuffer(); + for (int i = 0; i < byteArray.length; i++) { + hexStringBuffer.append(byteToHex(byteArray[i])); + } + return hexStringBuffer.toString(); + } + @Activate public void run() { LOG.info("Token renewal triggered."); @@ -392,8 +460,7 @@ public void run() { config.getKeystoreName(), config.getKeystorePassword(), config.getKeystoreAliasName(), - config.getTruststoreName(), - config.getConnectorUUID()); + config.getTruststoreName()); } catch (Exception e) { LOG.error("Token renewal failed", e); diff --git a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java index 40cdbc205..6fad55564 100644 --- a/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java +++ b/ids-webconsole/src/main/java/de/fhg/aisec/ids/webconsole/api/ConfigApi.java @@ -106,8 +106,7 @@ public String set(ConnectorConfig config) { config.getKeystoreName(), config.getKeystorePassword(), config.getKeystoreAliasName(), - config.getTruststoreName(), - config.getConnectorUUID()); + config.getTruststoreName()); } catch (Exception e) { e.printStackTrace(); } diff --git a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html b/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html index 1650937a8..dfd31343f 100644 --- a/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html +++ b/ids-webconsole/src/main/resources/www/src/app/ids/ids.component.html @@ -116,13 +116,6 @@

Settings

Valid truststore name required -
- - - Valid UUID required -
-