DieTechniker / secon-tool

Verschlüsselung nach GKV Datenaustausch (SECON)
GNU Lesser General Public License v3.0
21 stars 7 forks source link

Add fun-io-bios library to JAR #27

Closed lukasnaske closed 4 years ago

lukasnaske commented 4 years ago

When trying to use the released version of the secon-tool, I realized the dependency global.namespace.fun-io:fun-io-bios:2.4.0 was missing and had to be added in our pom.xml. After checking the released pom file for the secon-tool I realised that the dependencies are defined with <scope>runtime</scope>, is this intended?

For the bouncycastle dependency this is actually quite beneficial as it avoids clashes with the already existing bouncycastle version in our implementation, but for the fun-io-bios I would prefer to get the dependency from the secon-tool library as we do not use it anywhere else.

    <dependency>
      <groupId>global.namespace.fun-io</groupId>
      <artifactId>fun-io-bios</artifactId>
      <version>2.4.0</version>
      <scope>runtime</scope>
    </dependency>

Error shown when using trying to compile the project without specifying the fun-io-bios in the projects pom.xml:

java: cannot access global.namespace.fun.io.api.Socket
  class file for global.namespace.fun.io.api.Socket not found
christian-schlichtherle commented 4 years ago

The runtime scope on fun-io-bios is intentional indeed. Please note that the Socket interface is not from this library however. In fact, it is from another library fun-io-api, which is a transitive dependency of fun-io-bios. Apparently your tool chain does not resolve transitive dependencies? Please check.

christian-schlichtherle commented 4 years ago

This is how the dependency graph actually looks:

[info]   +-de.tk.opensource:secon-tool:1.0.0
[info]   | +-global.namespace.fun-io:fun-io-bios:2.4.0
[info]   | | +-global.namespace.fun-io:fun-io-spi:2.4.0
[info]   | |   +-global.namespace.fun-io:fun-io-api:2.4.0
[info]   | |   
[info]   | +-org.bouncycastle:bcpkix-jdk15on:1.66
[info]   |   +-org.bouncycastle:bcprov-jdk15on:1.66
lukasnaske commented 4 years ago

Thanks for this info. Still compilation fails, even with a clean project. As soon as Subscriber#signAndEncryptTo is called the Socket dependency cannot be found. I created a clean project using both gradle and maven and only tried to run a simple class:

public class Test {

    public static void main(String[] args) {
        Identity identity = SECON.identity(null, null, null);
        Directory directory = SECON.directory((KeyStore) null);
        Subscriber subscriber = SECON.subscriber(identity, directory);
        subscriber.signAndEncryptTo(() -> new ByteArrayOutputStream(), "test");
    }
}

I will investigate further, but it would be quite interesting if anyone else can successfully compile a project without adding the fun-io-bios dependency separately.

loetifuss commented 4 years ago

Just confirmed this issue with the following plain-vanilla Gradle script:

plugins {
    id 'java-library'
}

repositories {
    jcenter()
}

dependencies {
    implementation ('de.tk.opensource:secon-tool:1.0.0')    
}

Compilation of "Test.java" class fails on the command line using "gradlew compileJava". In Eclipse it works since Eclipse exposes the runtime classpath to the project.

christian-schlichtherle commented 4 years ago

Works like a charm for me. In pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>untitled</artifactId>
    <version>0.1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>de.tk.opensource</groupId>
            <artifactId>secon-tool</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>standalone</shadedClassifierName>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                        <exclude>**/module-info.class</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>de.tk.opensource.secon.Main</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Now in a shell session:

$ mvn clean verify
[...]
$ keytool -keystore keystore.p12 -storepass secret -genkey -alias alice -dname CN=alice -keyalg rsa
Generating 2.048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 90 days
        for: CN=alice
$ keytool -keystore keystore.p12 -storepass secret -genkey -alias bob -dname CN=bob -keyalg rsa
Generating 2.048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 90 days
        for: CN=bob
$ echo 'Hello world!' > message.txt
$ java -jar target/untitled-0.1.0-SNAPSHOT-standalone.jar -keystore keystore.p12 -storepass secret -alias alice -recipient bob -source message.txt -sink message.cms
$ java -jar target/untitled-0.1.0-SNAPSHOT-standalone.jar -keystore keystore.p12 -storepass secret -alias bob -source message.cms -sink copy.txt
$ cmp message.txt copy.txt
christian-schlichtherle commented 4 years ago
$ mvn dependency:tree
[...]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ untitled ---
[INFO] org.example:untitled:jar:0.1.0-SNAPSHOT
[INFO] \- de.tk.opensource:secon-tool:jar:1.0.0:compile
[INFO]    +- global.namespace.fun-io:fun-io-bios:jar:2.4.0:runtime
[INFO]    |  \- global.namespace.fun-io:fun-io-spi:jar:2.4.0:runtime
[INFO]    |     \- global.namespace.fun-io:fun-io-api:jar:2.4.0:runtime
[INFO]    \- org.bouncycastle:bcpkix-jdk15on:jar:1.66:runtime
[INFO]       \- org.bouncycastle:bcprov-jdk15on:jar:1.66:runtime
[INFO] ------------------------------------------------------------------------
[...]
$ 
christian-schlichtherle commented 4 years ago

This is how the dependency graph actually looks:

[info]   +-de.tk.opensource:secon-tool:1.0.0
[info]   | +-global.namespace.fun-io:fun-io-bios:2.4.0
[info]   | | +-global.namespace.fun-io:fun-io-spi:2.4.0
[info]   | |   +-global.namespace.fun-io:fun-io-api:2.4.0
[info]   | |   
[info]   | +-org.bouncycastle:bcpkix-jdk15on:1.66
[info]   |   +-org.bouncycastle:bcprov-jdk15on:1.66

This is from SBT, by the way. I suppose this issue is specific to Gradle.

loetifuss commented 4 years ago

The issue is compiling against secon-tool doesn't work, during runtime there is no problem. The compiler needs the "Socket" type of "fun-io-api" during compilation although it is marked as "implementation" scope. Thus, the POM file will only contain it as "runtime" dependency. I suspect the dependency on "Socket" is leaked in "de.tk.opensource.secon.SECON" class and therefore required through static imports in "de.tk.opensource.secon.Subscriber".

loetifuss commented 4 years ago

created a pull request to address this issue: https://github.com/DieTechniker/secon-tool/pull/28 Extracted API to interface to hide dependencies for compilation

lukasnaske commented 4 years ago

Thanks for taking care of this, with the newly released version the compilation works 💪