Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .githooks/pre-commit → .githooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
# limitations under the License.
#

echo "Running pre-commit hook"
echo "Running pre-push hook"

echo "Running format and lint checks"
if ! ./gradlew ktlintFormat licenseHeaderCheck detekt; then
if ! ./gradlew ktlintFormat detekt; then
echo "Lint errors detected. Commit aborted."
exit 1
fi
Expand Down
83 changes: 83 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: "CodeQL Analysis"

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '27 0 * * 2'

jobs:
analyze:
name: Analyze C/C++ and Java/Kotlin
runs-on: 'ubuntu-latest'
permissions:
# required for all workflows
security-events: write

# required to fetch internal or private CodeQL packs
packages: read

# only required for workflows in private repositories
actions: read
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
cache: gradle
distribution: 'temurin'
- name: Install dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y cmake swig ninja-build clang clang-tools libc++-dev libc++abi-dev
# - name: Install latest cmake
# run: |
# CMAKE_URL="https://github.com/Kitware/CMake/releases/latest/download/cmake-4.0.0-linux-x86_64.sh"
# EXPECTED_HASH="33ba237f2850a82d5c71c1d41803ab832a9a7aac7d99fa6e48bbe5bb4d66653c"
#
# wget "$CMAKE_URL" -O cmake-installer.sh
# echo "$EXPECTED_HASH cmake-installer.sh" | sha256sum -c -
#
# chmod +x cmake-installer.sh
# sudo ./cmake-installer.sh --skip-license --prefix=/usr/local
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Setup Android NDK
shell: bash
run: |
sdkmanager "ndk;27.2.12479018"
sdkmanager "cmake;3.31.6"
echo "ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/27.2.12479018" >> $GITHUB_ENV
echo "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH

# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: c-cpp, java-kotlin
build-mode: manual

- name: Build
shell: bash
env:
CC: clang
CXX: clang++
CXXFLAGS: --stdlib=libc++
run: |
./gradlew assemble

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@ xcuserdata
.kotlin
#So we don't accidentally commit our private keys
*.gpg

# Local Netlify folder
.netlify
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Ensure all the following pre-requirements are done:
Use the predefined Git hooks to ensure code quality and consistency. Run the following command from the root directory:

```sh
chmod +x .githooks/pre-commit
chmod +x .githooks/pre-push
git config core.hooksPath .githooks
````

Expand Down
64 changes: 37 additions & 27 deletions asn1/api/asn1.api
Original file line number Diff line number Diff line change
Expand Up @@ -85,39 +85,62 @@ public final class de/gematik/openhealth/asn1/Asn1EncoderKt {
}

public final class de/gematik/openhealth/asn1/Asn1GeneralizedTime {
public fun <init> (IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset;)V
public fun <init> (IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;)V
public final fun component1 ()I
public final fun component2 ()I
public final fun component3 ()I
public final fun component4 ()I
public final fun component5 ()Ljava/lang/Integer;
public final fun component6 ()Ljava/lang/Integer;
public final fun component7 ()Ljava/lang/Integer;
public final fun component8 ()Lde/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset;
public final fun copy (IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset;)Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset;ILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;
public final fun component8 ()Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;
public final fun copy (IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;)Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;IIIILjava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;ILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1GeneralizedTime;
public fun equals (Ljava/lang/Object;)Z
public final fun getDay ()I
public final fun getFractionOfSecond ()Ljava/lang/Integer;
public final fun getHour ()I
public final fun getMinute ()Ljava/lang/Integer;
public final fun getMonth ()I
public final fun getOffset ()Lde/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset;
public final fun getOffset ()Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;
public final fun getSecond ()Ljava/lang/Integer;
public final fun getYear ()I
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class de/gematik/openhealth/asn1/Asn1GeneralizedTime$Offset {
public final class de/gematik/openhealth/asn1/Asn1ObjectIdentifierKt {
public static final fun readObjectIdentifier (Lde/gematik/openhealth/asn1/Asn1Decoder$ParserScope;)Ljava/lang/String;
public static final fun writeObjectIdentifier (Lde/gematik/openhealth/asn1/Asn1Encoder$WriterScope;Ljava/lang/String;)V
}

public abstract class de/gematik/openhealth/asn1/Asn1Offset {
}

public final class de/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset : de/gematik/openhealth/asn1/Asn1Offset {
public fun <init> (II)V
public final fun component1 ()I
public final fun component2 ()I
public final fun copy (II)Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;IIILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1Offset$GeneralizedOffset;
public fun equals (Ljava/lang/Object;)Z
public final fun getHours ()I
public final fun getMinutes ()I
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class de/gematik/openhealth/asn1/Asn1ObjectIdentifierKt {
public static final fun readObjectIdentifier (Lde/gematik/openhealth/asn1/Asn1Decoder$ParserScope;)Ljava/lang/String;
public static final fun writeObjectIdentifier (Lde/gematik/openhealth/asn1/Asn1Encoder$WriterScope;Ljava/lang/String;)V
public final class de/gematik/openhealth/asn1/Asn1Offset$UtcOffset : de/gematik/openhealth/asn1/Asn1Offset {
public fun <init> (II)V
public final fun component1 ()I
public final fun component2 ()I
public final fun copy (II)Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;IIILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;
public fun equals (Ljava/lang/Object;)Z
public final fun getHours ()I
public final fun getMinutes ()I
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class de/gematik/openhealth/asn1/Asn1Tag {
Expand Down Expand Up @@ -179,38 +202,25 @@ public final class de/gematik/openhealth/asn1/Asn1Type {
}

public final class de/gematik/openhealth/asn1/Asn1UtcTime {
public fun <init> (IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;)V
public fun <init> (IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;)V
public final fun component1 ()I
public final fun component2 ()I
public final fun component3 ()I
public final fun component4 ()I
public final fun component5 ()I
public final fun component6 ()Ljava/lang/Integer;
public final fun component7 ()Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;
public final fun copy (IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;)Lde/gematik/openhealth/asn1/Asn1UtcTime;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1UtcTime;IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;ILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1UtcTime;
public final fun component7 ()Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;
public final fun copy (IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;)Lde/gematik/openhealth/asn1/Asn1UtcTime;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1UtcTime;IIIIILjava/lang/Integer;Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;ILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1UtcTime;
public fun equals (Ljava/lang/Object;)Z
public final fun getDay ()I
public final fun getHour ()I
public final fun getMinute ()I
public final fun getMonth ()I
public final fun getOffset ()Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;
public final fun getOffset ()Lde/gematik/openhealth/asn1/Asn1Offset$UtcOffset;
public final fun getSecond ()Ljava/lang/Integer;
public final fun getYear ()I
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class de/gematik/openhealth/asn1/Asn1UtcTime$Offset {
public fun <init> (II)V
public final fun component1 ()I
public final fun component2 ()I
public final fun copy (II)Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;
public static synthetic fun copy$default (Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;IIILjava/lang/Object;)Lde/gematik/openhealth/asn1/Asn1UtcTime$Offset;
public fun equals (Ljava/lang/Object;)Z
public final fun getHours ()I
public final fun getMinutes ()I
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

4 changes: 4 additions & 0 deletions crypto-jvm-lib/api/crypto-jvm-lib.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
public final class de/gematik/openhealth/crypto/internal/interop/NativeLoaderKt {
public static final fun loadNativeLibrary ()V
}

16 changes: 9 additions & 7 deletions crypto-jvm-lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

plugins {
id("java-library")
kotlin("jvm")
id("maven-publish")
}

Expand All @@ -24,15 +24,13 @@ version = project.findProperty("gematik.version") as String

val rootOutputDir = "${layout.buildDirectory.get().asFile}/generated/"

java {
kotlin {
jvmToolchain(17)
sourceSets {
main {
resources.srcDir("$rootOutputDir/resources")
}
}

sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

val hostOs =
Expand Down Expand Up @@ -98,10 +96,14 @@ val copyNativeLibs by tasks.registering(Copy::class) {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

tasks.named<Jar>("jar") {
tasks.named("jar") {
dependsOn(copyNativeLibs)
}

tasks.named("processTestResources") {
dependsOn(copyNativeLibs)
}

tasks.named<ProcessResources>("processResources") {
tasks.named("processResources") {
dependsOn(copyNativeLibs)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2025 gematik GmbH
*
* 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.
*/

package de.gematik.openhealth.crypto.internal.interop
import java.io.File

private val hostOs =
System
.getProperty("os.name")
.lowercase()
.trim()
.replace(" ", "")
private val hostArch =
System
.getProperty("os.arch")
.lowercase()
.trim()
.replace(" ", "")

@Suppress("UnsafeDynamicallyLoadedCode")
fun loadNativeLibrary() {
try {
System.loadLibrary("oh_crypto")
} catch (_: UnsatisfiedLinkError) {
val libName =
when {
hostOs.contains("mac") -> "liboh_crypto.dylib"
hostOs.contains("win") -> "oh_crypto.dll"
else -> "liboh_crypto.so"
}

val libResUrl = ClassLoader.getSystemResource("$hostOs-$hostArch/$libName")

val tempLib = File.createTempFile("lib", libName)
tempLib.deleteOnExit()
libResUrl.openStream().copyTo(tempLib.outputStream())

System.load(tempLib.absolutePath)
}
}
Loading