aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/nix.yml59
-rw-r--r--README.md32
-rw-r--r--flake.nix81
-rw-r--r--nix/fetch_releases.py149
4 files changed, 176 insertions, 145 deletions
diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml
index 71efe06..9c3ff62 100644
--- a/.github/workflows/nix.yml
+++ b/.github/workflows/nix.yml
@@ -50,3 +50,62 @@ jobs:
- name: List library
run: nix run ".?submodules=1#${{ matrix.library }}.default" -- list-libs
+
+ reader:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ name: Build reader
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-tags: true
+ fetch-depth: -1
+
+ - uses: DeterminateSystems/nix-installer-action@v13
+ with:
+ diagnostic-endpoint: ""
+
+ - uses: DeterminateSystems/magic-nix-cache-action@v7
+ with:
+ diagnostic-endpoint: ""
+
+ - name: Build reader
+ run: |
+ nix build ".?submodules=1#reader"
+
+ - name: Show reader --help
+ run: |
+ nix run ".?submodules=1#reader" -- --help
+
+ applet:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ strategy:
+ matrix:
+ sdk: [ "222", "305", "320", "All" ]
+ fail-fast: false
+
+ name: Build applet ${{ matrix.sdk }}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-tags: true
+ fetch-depth: -1
+
+ - uses: DeterminateSystems/nix-installer-action@v13
+ with:
+ diagnostic-endpoint: ""
+
+ - uses: DeterminateSystems/magic-nix-cache-action@v7
+ with:
+ diagnostic-endpoint: ""
+
+ - name: Build applet
+ run: |
+ nix build ".?submodules=1#applet${{ matrix.sdk }}"
diff --git a/README.md b/README.md
index 1766b60..3e391b8 100644
--- a/README.md
+++ b/README.md
@@ -348,21 +348,41 @@ nix build "#lib.openssl.v331"
# To build a shim using a given version of a library (example mbedTLS 3.5):
nix build "#shim.mbedtls.v35"
# To build ECTesterStandalone.jar with a given version of a library (example libgcrypt 1.9.4):
-nix build "?submodules=1#gcrypt.v194"
+nix build ".?submodules=1#gcrypt.v194"
# The available versions of the libraries are in the nix/*_pkg_versions.json files.
# The "default" version always points to the most recent version.
# To build ECTesterStandalone with all the libraries in default versions:
-nix build "?submodules=1#"
+nix build ".?submodules=1#"
```
-Each of the build steps above puts (symlinks really) its results into `./result` directory.
-However, subsequent builds then replace that with their own results. To run ECTesterStandalone
-with a given library version and arguments do:
+Each of the build steps above puts (symlinks really) its results into `./result` directory (use `-o/--out-link {path}`
+to change that directory). However, subsequent builds then replace that with their own results. To run
+ECTesterStandalone with a given library version and arguments do:
```shell
# This runs the default test-suite agains LibreSSL 3.9.2
-nix run "?submodules=1#libressl.v392" -- test default LibreSSL
+nix run ".?submodules=1#libressl.v392" -- test default LibreSSL
+```
+
+To build the JavaCard applets:
+```shell
+nix build ".?submodules=1#applets"
+# or individually
+nix build ".?submodules=1#applet222"
+nix build ".?submodules=1#applet305"
+nix build ".?submodules=1#applet320"
+```
+
+To build or run the reader you can:
+```shell
+nix build '.?submodules=1#reader'
+nix run '.?submodules=1#reader'
+```
+
+If needed, you can also build the `common` library:
+```shell
+nix build '.?submodules=1#common'
```
#### Gradle
diff --git a/flake.nix b/flake.nix
index 6ca0ef9..446c495 100644
--- a/flake.nix
+++ b/flake.nix
@@ -689,6 +689,73 @@
}
);
+ buildReader =
+ with pkgs;
+ {
+ jdkVersion ? jdk17_headless,
+ }:
+ gradle2nix.builders.${system}.buildGradlePackage rec {
+ pname = "ECTesterReader";
+ version = "0.3.3";
+ lockFile = ./gradle.lock;
+ buildJdk = pkgs.jdk_headless;
+ gradleBuildFlags = [ ":reader:uberJar" ];
+ src = ./.;
+
+ installPhase = ''
+ mkdir -p $out
+ cp -r reader/build $out
+ '';
+
+ nativeBuildInputs = [ makeWrapper ];
+
+ postFixup = ''
+ makeWrapper \
+ ${jdk_headless}/bin/java $out/bin/${pname} \
+ --add-flags "-Dstdout.encoding=UTF8 -Dstderr.encoding=UTF8 -jar $out/build/libs/${pname}.jar"
+ '';
+ };
+
+ buildApplet =
+ with pkgs;
+ {
+ jdkVersion ? jdk8_headless,
+ }:
+ gradle2nix.builders.${system}.buildGradlePackage rec {
+ pname = "applet";
+ # since the gradle target builds applets for multiple JC SDKs, the
+ # single version cannot reflet that
+ version = "0.3.3";
+ lockFile = ./gradle.lock;
+ buildJdk = jdkVersion;
+ gradleBuildFlags = [ ":applet:buildJavaCard" ];
+ src = ./.;
+
+ installPhase = ''
+ mkdir --parents $out
+ cp --recursive applet/build/* $out
+ '';
+ };
+
+ buildCommon =
+ with pkgs;
+ {
+ jdkVersion ? jdk17_headless,
+ }:
+ gradle2nix.builders.${system}.buildGradlePackage rec {
+ pname = "common";
+ version = "0.3.3";
+ lockFile = ./gradle.lock;
+ buildJdk = jdkVersion;
+ gradleBuildFlags = [ ":common:build" ];
+ src = ./.;
+
+ installPhase = ''
+ mkdir --parents $out
+ cp --recursive common/build/* $out
+ '';
+ };
+
defaultVersion =
# Default version is the last one, aka the newest that we fetched
libName:
@@ -774,6 +841,20 @@
function = buildECTesterStandalone;
};
+ reader = buildReader { };
+ common = buildCommon { };
+ appletAll = pkgs.buildEnv {
+ name = "applets";
+ paths = [
+ applet222
+ applet305
+ applet320
+ ];
+ };
+ applet222 = buildApplet { jdkVersion = pkgs.jdk8_headless; };
+ applet305 = buildApplet { jdkVersion = pkgs.jdk8_headless; };
+ applet320 = buildApplet { jdkVersion = pkgs.jdk17_headless; };
+
shim = {
tomcrypt = loadVersionsForShim {
libName = "tomcrypt";
diff --git a/nix/fetch_releases.py b/nix/fetch_releases.py
index d8e5df5..c132f3e 100644
--- a/nix/fetch_releases.py
+++ b/nix/fetch_releases.py
@@ -1,32 +1,17 @@
#!/usr/bin/env python3
import argparse
-
import json
-import jinja2
import re
import requests
import shutil
import tempfile
-
import pathlib
import subprocess as sp
-
from base64 import b32encode, b32decode, b64encode, b16decode
from bs4 import BeautifulSoup
from packaging.version import parse as parse_version, Version
-env = jinja2.Environment()
-
-all_versions_template = env.from_string(
- """{
- buildECTesterStandalone
-}:
-{ {% for version in pkg_versions %}
- {{ version }} {% endfor %}
-}"""
-)
-
def get_source_hash(url, unpack=False):
digest_type = "sha256"
@@ -48,7 +33,7 @@ def get_source_hash(url, unpack=False):
return digest_sri
-def serialize_versions(pkg, renders, versions):
+def serialize_versions(pkg, versions):
sorted_versions = {
k: {kk: vv for kk, vv in v.items() if kk != "sort"}
for k, v in sorted(
@@ -56,10 +41,6 @@ def serialize_versions(pkg, renders, versions):
)
}
- # all_versions = all_versions_template.render(pkg_versions=renders).strip()
- # with open(f"./nix/{pkg}_pkg_versions.nix", "w") as handle:
- # handle.write(all_versions)
-
with open(f"./nix/{pkg}_pkg_versions.json", "w") as handle:
json.dump(sorted_versions, handle, indent=4)
@@ -72,13 +53,6 @@ def fetch_botan():
resp = requests.get(release_list)
soup = BeautifulSoup(resp.content, "html.parser")
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; source_extension="{{ ext }}"; hash="{{ digest }}"; };
- };"""
- )
-
- renders = []
versions = {}
for link in soup.find_all("a"):
if link.text.startswith("Botan") and not link.text.endswith(".asc"):
@@ -100,21 +74,13 @@ def fetch_botan():
flat_version = f"v{match['major']}{match['minor']}{match['patch']}"
print(f"{version}:{digest}")
- rendered = single_version_template.render(
- pkg=pkg,
- digest=digest,
- ext=ext,
- flat_version=flat_version,
- version=version,
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"source_extension": ext,
"hash": digest,
"sort": parse_version(version),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_cryptopp():
@@ -129,7 +95,6 @@ def fetch_cryptopp():
{{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
};"""
)
- renders = []
versions = {}
for release in resp.json():
if not release["draft"] and not release["prerelease"]:
@@ -140,19 +105,12 @@ def fetch_cryptopp():
digest = get_source_hash(download_url, unpack=True)
print(f"{underscored_version}:{digest}")
- rendered = single_version_template.render(
- pkg=pkg,
- digest=digest,
- flat_version=flat_version,
- version=underscored_version,
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": underscored_version,
"hash": digest,
"sort": parse_version(underscored_version.replace("_", ".")),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_openssl():
@@ -186,12 +144,6 @@ def fetch_openssl():
)
)
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
- };"""
- )
- renders = []
versions = {}
for tag in tags:
if tag.startswith("OpenSSL_"):
@@ -223,12 +175,7 @@ def fetch_openssl():
"hash": digest,
"sort": parse_version(sort_version),
}
-
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=flat_version, version=dotted_version
- ).strip()
- renders.append(rendered)
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_tomcrypt():
@@ -243,53 +190,32 @@ def fetch_gcrypt():
resp = requests.get(release_list)
soup = BeautifulSoup(resp.content, "html.parser")
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
- };"""
- )
-
- renders = []
versions = {}
for link in soup.find_all("a"):
if link.text.startswith("libgcrypt") and link.text.endswith("tar.bz2"):
download_link = download_url.format(version=link["href"])
-
match = re.match(
r"libgcrypt-(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<dont>_do_not_use)?\.(?P<ext>.*)",
link.text,
)
version = f"{match['major']}.{match['minor']}.{match['patch']}"
-
digest = get_source_hash(download_link)
print(f"{version}:{digest}")
-
flat_version = f"v{match['major']}{match['minor']}{match['patch']}"
if match["dont"]:
flat_version += "_do_not_use"
-
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=flat_version, version=version
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"hash": digest,
"sort": parse_version(version),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_boringssl():
pkg = "boringssl"
upto = "76bb1411acf5cf6935586182a3a037d372ed1636"
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { rev="{{ rev }}"; hash="{{ digest }}"; };
- };"""
- )
- renders = []
versions = {}
with (
tempfile.TemporaryDirectory() as repodir,
@@ -302,7 +228,6 @@ def fetch_boringssl():
)
# NOTE: we need to get rid of the .git so that it is not included in the derivation hash
shutil.move(repodir / ".git", gitdir)
-
output = sp.check_output(
[
"git",
@@ -315,7 +240,6 @@ def fetch_boringssl():
]
)
refs = output.decode().split("\n")
-
upto_index = refs.index(upto)
# pick roughly every 40th commit from the "upto" commit
@@ -338,13 +262,8 @@ def fetch_boringssl():
)
print(f"{i + 1: 4d}:{rev}:{digest}")
abbrev_commit = str(rev[:8])
-
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=f"r{abbrev_commit}", rev=rev
- ).strip()
- renders.append(rendered)
versions[f"r{abbrev_commit}"] = {"rev": rev, "hash": digest, "sort": i}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_mbedtls():
@@ -355,12 +274,6 @@ def fetch_mbedtls():
release_url = f"https://api.github.com/repos/{owner}/{repo}/releases"
resp = requests.get(release_url)
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
- };"""
- )
- renders = []
versions = {}
for release in resp.json():
if not release["draft"] and not release["prerelease"]:
@@ -377,20 +290,14 @@ def fetch_mbedtls():
digest = "sha256-tSWhF8i0Tx9QSFmyDEHdd2xveZvpyd+HXR+8xYj2Syo="
else:
digest = get_source_hash(download_url, unpack=True)
-
print(f"{version}:{digest}")
-
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=flat_version, version=version
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"hash": digest,
"tag": tag,
"sort": parse_version(version),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_ippcp():
@@ -401,12 +308,6 @@ def fetch_ippcp():
release_url = f"https://api.github.com/repos/{owner}/{repo}/releases"
resp = requests.get(release_url)
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
- };"""
- )
- renders = []
versions = {}
for release in resp.json():
if not release["draft"] and not release["prerelease"]:
@@ -422,16 +323,12 @@ def fetch_ippcp():
digest = get_source_hash(download_url, unpack=True)
print(f"{version}:{digest}")
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=flat_version, version=version
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"hash": digest,
"sort": (1, parsed) if parsed.major < 2000 else (0, parsed),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_nettle():
@@ -442,12 +339,6 @@ def fetch_nettle():
release_url = f"https://api.github.com/repos/{owner}/{repo}/tags"
resp = requests.get(release_url)
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; tag="{{ tag }}"; hash="{{ digest }}"; };
- };"""
- )
- renders = []
versions = {}
for tag in resp.json():
if tag["name"] == "release_nettle_0.2.20010617":
@@ -465,21 +356,13 @@ def fetch_nettle():
digest = get_source_hash(download_url, unpack=False)
print(f"{version}:{digest}")
- rendered = single_version_template.render(
- pkg=pkg,
- digest=digest,
- flat_version=flat_version,
- tag=tag["name"],
- version=version,
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"tag": tag["name"],
"hash": digest,
"sort": parse_version(version),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def fetch_libressl():
@@ -489,13 +372,6 @@ def fetch_libressl():
resp = requests.get(release_list)
soup = BeautifulSoup(resp.content, "html.parser")
- single_version_template = env.from_string(
- """{{ flat_version }} = buildECTesterStandalone {
- {{ pkg }} = { version="{{ version }}"; hash="{{ digest }}"; };
- };"""
- )
-
- renders = []
versions = {}
for link in soup.find_all("a"):
if link.text.startswith("libressl") and link.text.endswith(".tar.gz"):
@@ -509,17 +385,12 @@ def fetch_libressl():
print(f"{version}:{digest}")
# NOTE: use underscore to separate the versions?
flat_version = f"v{match['major']}{match['minor']}{match['patch']}"
-
- rendered = single_version_template.render(
- pkg=pkg, digest=digest, flat_version=flat_version, version=version
- ).strip()
- renders.append(rendered)
versions[flat_version] = {
"version": version,
"hash": digest,
"sort": parse_version(version),
}
- serialize_versions(pkg, renders, versions)
+ serialize_versions(pkg, versions)
def main():