From 7c088a6afb24fc4945f0f8a2587843e4b82e28f3 Mon Sep 17 00:00:00 2001 From: Nikolai Prokoschenko Date: Mon, 3 Jun 2024 10:59:07 +0200 Subject: [PATCH] Address comments on the "rootless CA certs" patch Address the following problems with #538: 1. Correct the shell selection for entrypoint, Ubuntu flavours still need explicit `bash` for variables with dots in their names 2. Change unhelpful exported variable name (changed from `CACERT` to `JRE_CACERTS_PATH`) 3. Change `which` to more-POSIX-compatible `command -v` 4. More cleanup 5. Explicitely use `TMPDIR` when available instead of hard-coded `/tmp` 6. Support multi-certificate files (again) 7. Make output less verbose --- .../{dockerbuilder.crt => .dockerbuilder.crt} | 0 .../{dockerbuilder.key => .dockerbuilder.key} | 0 .../certs/.dockerbuilder2.crt | 20 +++++++ .../certs/.dockerbuilder2.key | 28 ++++++++++ .../certs/README.md | 10 +++- .../certs/multi-cert.crt | 40 ++++++++++++++ .../certs_symlink/.dockerbuilder2.crt | 20 +++++++ .../certs_symlink/.dockerbuilder2.key | 28 ++++++++++ .../certs_symlink/.multi-cert.crt | 40 ++++++++++++++ .../certs_symlink/README.md | 10 +++- .../certs_symlink/dockerbuilder.crt | 1 - .../certs_symlink/multi-cert.crt | 1 + .../tests/java-ca-certificates-update/run.sh | 2 +- 11/jdk/alpine/Dockerfile | 5 ++ 11/jdk/alpine/entrypoint.sh | 54 +++++++++++++------ 11/jdk/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 11/jdk/ubuntu/focal/Dockerfile | 2 +- 11/jdk/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 11/jdk/ubuntu/jammy/Dockerfile | 2 +- 11/jdk/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 11/jdk/ubuntu/noble/Dockerfile | 2 +- 11/jdk/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 11/jre/alpine/Dockerfile | 5 ++ 11/jre/alpine/entrypoint.sh | 54 +++++++++++++------ 11/jre/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 11/jre/ubuntu/focal/Dockerfile | 2 +- 11/jre/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 11/jre/ubuntu/jammy/Dockerfile | 2 +- 11/jre/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 11/jre/ubuntu/noble/Dockerfile | 2 +- 11/jre/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 17/jdk/alpine/Dockerfile | 5 ++ 17/jdk/alpine/entrypoint.sh | 54 +++++++++++++------ 17/jdk/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 17/jdk/ubuntu/focal/Dockerfile | 2 +- 17/jdk/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 17/jdk/ubuntu/jammy/Dockerfile | 2 +- 17/jdk/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 17/jdk/ubuntu/noble/Dockerfile | 2 +- 17/jdk/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 17/jre/alpine/Dockerfile | 5 ++ 17/jre/alpine/entrypoint.sh | 54 +++++++++++++------ 17/jre/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 17/jre/ubuntu/focal/Dockerfile | 2 +- 17/jre/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 17/jre/ubuntu/jammy/Dockerfile | 2 +- 17/jre/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 17/jre/ubuntu/noble/Dockerfile | 2 +- 17/jre/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 21/jdk/alpine/Dockerfile | 5 ++ 21/jdk/alpine/entrypoint.sh | 54 +++++++++++++------ 21/jdk/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 21/jdk/ubuntu/jammy/Dockerfile | 2 +- 21/jdk/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 21/jdk/ubuntu/noble/Dockerfile | 2 +- 21/jdk/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 21/jre/alpine/Dockerfile | 5 ++ 21/jre/alpine/entrypoint.sh | 54 +++++++++++++------ 21/jre/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 21/jre/ubuntu/jammy/Dockerfile | 2 +- 21/jre/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 21/jre/ubuntu/noble/Dockerfile | 2 +- 21/jre/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 22/jdk/alpine/Dockerfile | 5 ++ 22/jdk/alpine/entrypoint.sh | 54 +++++++++++++------ 22/jdk/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 22/jdk/ubuntu/jammy/Dockerfile | 2 +- 22/jdk/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 22/jdk/ubuntu/noble/Dockerfile | 2 +- 22/jdk/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 22/jre/alpine/Dockerfile | 5 ++ 22/jre/alpine/entrypoint.sh | 54 +++++++++++++------ 22/jre/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 22/jre/ubuntu/jammy/Dockerfile | 2 +- 22/jre/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 22/jre/ubuntu/noble/Dockerfile | 2 +- 22/jre/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 8/jdk/alpine/Dockerfile | 5 ++ 8/jdk/alpine/entrypoint.sh | 54 +++++++++++++------ 8/jdk/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 8/jdk/ubuntu/focal/Dockerfile | 2 +- 8/jdk/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 8/jdk/ubuntu/jammy/Dockerfile | 2 +- 8/jdk/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 8/jdk/ubuntu/noble/Dockerfile | 2 +- 8/jdk/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ 8/jre/alpine/Dockerfile | 5 ++ 8/jre/alpine/entrypoint.sh | 54 +++++++++++++------ 8/jre/ubi/ubi9-minimal/entrypoint.sh | 54 +++++++++++++------ 8/jre/ubuntu/focal/Dockerfile | 2 +- 8/jre/ubuntu/focal/entrypoint.sh | 54 +++++++++++++------ 8/jre/ubuntu/jammy/Dockerfile | 2 +- 8/jre/ubuntu/jammy/entrypoint.sh | 54 +++++++++++++------ 8/jre/ubuntu/noble/Dockerfile | 2 +- 8/jre/ubuntu/noble/entrypoint.sh | 54 +++++++++++++------ config/hotspot.yml | 9 ++++ docker_templates/alpine-linux.Dockerfile.j2 | 7 ++- docker_templates/entrypoint.sh | 54 +++++++++++++------ docker_templates/ubuntu.Dockerfile.j2 | 4 +- generate_dockerfiles.py | 2 + 100 files changed, 2030 insertions(+), 832 deletions(-) rename .test/tests/java-ca-certificates-update/certs/{dockerbuilder.crt => .dockerbuilder.crt} (100%) rename .test/tests/java-ca-certificates-update/certs/{dockerbuilder.key => .dockerbuilder.key} (100%) create mode 100644 .test/tests/java-ca-certificates-update/certs/.dockerbuilder2.crt create mode 100644 .test/tests/java-ca-certificates-update/certs/.dockerbuilder2.key create mode 100644 .test/tests/java-ca-certificates-update/certs/multi-cert.crt create mode 100644 .test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.crt create mode 100644 .test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.key create mode 100644 .test/tests/java-ca-certificates-update/certs_symlink/.multi-cert.crt delete mode 120000 .test/tests/java-ca-certificates-update/certs_symlink/dockerbuilder.crt create mode 120000 .test/tests/java-ca-certificates-update/certs_symlink/multi-cert.crt mode change 100755 => 100644 docker_templates/entrypoint.sh diff --git a/.test/tests/java-ca-certificates-update/certs/dockerbuilder.crt b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder.crt similarity index 100% rename from .test/tests/java-ca-certificates-update/certs/dockerbuilder.crt rename to .test/tests/java-ca-certificates-update/certs/.dockerbuilder.crt diff --git a/.test/tests/java-ca-certificates-update/certs/dockerbuilder.key b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder.key similarity index 100% rename from .test/tests/java-ca-certificates-update/certs/dockerbuilder.key rename to .test/tests/java-ca-certificates-update/certs/.dockerbuilder.key diff --git a/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.crt b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.crt new file mode 100644 index 000000000..45861b02a --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRzCCAi+gAwIBAgIUZuRSLr7riMCDUFHVQKYQh/abmZQwDQYJKoZIhvcNAQEL +BQAwMjEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFzAVBgNVBAMMDkRvY2tlckJ1 +aWxkZXIyMCAXDTI0MDcyNDIxMDk0NloYDzMwMDQwOTI1MjEwOTQ2WjAyMRcwFQYK +CZImiZPyLGQBGRYHVGVtdXJpbjEXMBUGA1UEAwwORG9ja2VyQnVpbGRlcjIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSs004yyVW4dEREZgTGbN1Dzbc ++VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCnSlHIpU6Ax7tP +WGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP+N8d1taRSrhR +vbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV+JsmCf6oPDt4 +b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqpibaQbG1UTX1f +5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7kxAdOC/KTAgMB +AAGjUzBRMB0GA1UdDgQWBBQ1oKojBf5qgkezUk6axrz3CjdHmzAfBgNVHSMEGDAW +gBQ1oKojBf5qgkezUk6axrz3CjdHmzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQCDUUOV23QzoqeGs7CKHXg+Mvxn6E4Tm395c0RKJRiHXEueQ2JD +e7ywfb11f/vGyudWVKe1wiRuMP4U8G6V3m6C/CSJrz1J3N9fvN23iPaZIh1O0vSr +xOz5UmiSsRW8BEQYCvF8CoWim1fG+KjtRhO6QqKLtK11j6TwZaUBIvSwK+OZKSuw +q8SuBRXNrIJvH0bonOXcuivOkruU0aRdizIG5Ed0OV2PVfbw2gu7Om83ADbVuSOV +noMwGjDVzVRAs8lu4ijuAryshVQK0LkImrwp+YkhRkFus0HWJqi/Ox+BHZt3BiFs +ATt9J3LCLazvP6LGr4rlZixJqM2ZC7dP0lOl +-----END CERTIFICATE----- diff --git a/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.key b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.key new file mode 100644 index 000000000..b4fce7f80 --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs/.dockerbuilder2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDSs004yyVW4dER +EZgTGbN1Dzbc+VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCn +SlHIpU6Ax7tPWGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP ++N8d1taRSrhRvbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV ++JsmCf6oPDt4b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqp +ibaQbG1UTX1f5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7k +xAdOC/KTAgMBAAECggEAANIrB8nVtFbjVrmdnEqVs8drnITzVmYN+gxhaSTiQwuq +9dWyjY6+omPYVma94GKADlR7oXd+7cyLks65rrXRCdi0PaKw6vox9WdkMCY803zr +BWrouq0Hq1W0y3x3WOjrSyjOiTgdwhBDlLH1Vk/tV/VwybOa4dMeRKveFkNmbXKU +ZeR62r95vob4F5Ui6CWqSDRXFSml8VvBkU+6RAm697Lm5JQKoOuUueR9/L5z2Y0Z +rpGeBQ2tbbRIAvQWG3PhQirDqduL2e8aUs/RG8jGmbAnB9LoWJtaBEgLoza6221F +vboRWDLG5yZorXeGHT169+LQQ84rtwyjbQkvKjcP1QKBgQD632J17fWqK5cBaU2c +2bxAwS8aoqzPgBkAD2E8/VBEmJfjUAH5KVNuF9oeO/ho6JUOHoAWxMeu9v0ikynb +wnznQXlgieJCockJaTx1fkE/+W38uRXLK1TBSHFB7QdhPJbdeOh0jbsxNoX3wCAW +jQDUf2CoVdt+326II71IhDnnbQKBgQDXAbpkEWMYnWbl+WmSwGGud2AO7Uaw6ZQK +e83/zKQYcLsGHVMEJ41i2Lrd+VGJjK1eHUyOxHYg4Cel4cG5P7sU45yhehHVAeau +Z8KzQbB8BGcyMUoQFMIK5AXIiVdgTvt+aoKMEfXSAuZi1g5ATSS6zBoXWxlJyQ4b +R1MqOvMB/wKBgAw/3A7mD5i/iCAJhECkYQzIYgRq7QU0vAPEvHq94611xfTTc0U3 +P1ugzoWrZ/W3ZY/K7XYvJZDlfnaxuNmCJZclG0gbc3DNdYOAH/OctpLpGvW8E9RX +yUumveD6MeINk1A9FxyZzwoYH3J5bxeqyt+VWKLfjlgjkMIU/KkNy8YBAoGAbU2G +mTqxmyDh38YE4sMEpbIwVkZP6r5EMXQxDHrXbUlZ+sjLnFATM44kqZYG2pt2w2K3 +udisiRgLb+wuFOQOUpdH2Ft7V0NpJ36+X2zksJd4cu7VzQkQgILdYc5YajCc7+5r +wZOb2ZD52IMjqZLOOlxqYzc/yt/4WOvQnqZrRbcCgYBQopNwh9Hx9SBIHkkZkq1Z +iiPZl05khB/Vw76hABwjMillQd+nOJNf4kymIiOzfThEw/a4kam1zWvN0kq9Guu/ +YMvd73sqcudB5IWIjdqq0lKML2rcoBGqKGj5dFZt6Un/jqbi5nHeoMubrZkXUdG8 +PDtV2BTZDwmo+btPF//U5Q== +-----END PRIVATE KEY----- diff --git a/.test/tests/java-ca-certificates-update/certs/README.md b/.test/tests/java-ca-certificates-update/certs/README.md index b408dfed4..c5feb7d34 100644 --- a/.test/tests/java-ca-certificates-update/certs/README.md +++ b/.test/tests/java-ca-certificates-update/certs/README.md @@ -1 +1,9 @@ -This certificate/key pair has been generated with `openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder" -keyout certs/dockerbuilder.key -out certs/dockerbuilder.crt` and is only used for testing +These certificate/key pairs has been generated with + +``` shell +$ openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder" -keyout certs/dockerbuilder.key -out certs/dockerbuilder.crt +$ openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder2" -keyout certs/dockerbuilder2.key -out certs/dockerbuilder2.crt +$ cat certs/dockerbuilder.crt certs/dockerbuilder2.crt > certs/multi-cert.crt +``` + + and are only used for testing diff --git a/.test/tests/java-ca-certificates-update/certs/multi-cert.crt b/.test/tests/java-ca-certificates-update/certs/multi-cert.crt new file mode 100644 index 000000000..66293f662 --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs/multi-cert.crt @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUIfl8I/yasxlsTEc30PLLRuleiCswDQYJKoZIhvcNAQEL +BQAwMTEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFjAUBgNVBAMMDURvY2tlckJ1 +aWxkZXIwIBcNMjMwNjEyMTgyNDE1WhgPMzAwMzA4MTQxODI0MTVaMDExFzAVBgoJ +kiaJk/IsZAEZFgdUZW11cmluMRYwFAYDVQQDDA1Eb2NrZXJCdWlsZGVyMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArfOgmluNXEIE7BWvt7jGgdZW/y5s +N78FcpZdM8Z2FatvjJKvNmJ9OkkkOSNBhGKAWpHn19JMNdQ2nEmTHMetg0hiSqRI +hBceAY4lDfOzxAyZGGpVzL9U1B9mOrX5O3EedF5AVvl0NZVjEwswuGaUa3zZBAKy +Z5Vv/z8Lw2uYIs/dtw8lcpEAb78BZ8bAhhhl+X+tTGK8agibLGQJT9l/JxS3pXyw +me4YaKQQRgvuqOTEt+x+0aA5E2EUTOGq0Li+i1ranf6ou5Dz/Y6LtXwT/j2bf4ZR +w2YHpYZL54UEtMWES2KAjsZ3u4DCxUIEfW8EgxUIhcepIDP1h05A3fSiWQIDAQAB +o1MwUTAdBgNVHQ4EFgQUr0VirSzDQTuNgGjDxRkxPFrjUKcwHwYDVR0jBBgwFoAU +r0VirSzDQTuNgGjDxRkxPFrjUKcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQsFAAOCAQEAlo6ZSAIKSUWqRygyNg9oWuLGfWMW//dZjU1MKBYVpM4Mry/aMD5d +kMQj9hm+zXhNYN01yLh/cdPKCQ/r1KP6lmCtZHp50Xe8HEnIymRYx0KMAcqYLjnT +DXwCPqtWvJ1do65vVJRN70CuF8T1JNFhPdirrAiuU7bhGPABfnbek7yNkTYgUSdb +WpV/WOFPh9Dl24vNl1/Cti+pQThlCgHF/+dVndFHN9FOOG8k8ohYkLwL+ZzKfOiZ +CVWn2mWk2EhcuTlg/3zkXmwjfzFTdXMhS1sdfJNReaY/omJ91euxB0c8iYZV4wuU +ghx+GJ14nO7RJNHNX4k+BBPxy3f56+cYrg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDRzCCAi+gAwIBAgIUZuRSLr7riMCDUFHVQKYQh/abmZQwDQYJKoZIhvcNAQEL +BQAwMjEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFzAVBgNVBAMMDkRvY2tlckJ1 +aWxkZXIyMCAXDTI0MDcyNDIxMDk0NloYDzMwMDQwOTI1MjEwOTQ2WjAyMRcwFQYK +CZImiZPyLGQBGRYHVGVtdXJpbjEXMBUGA1UEAwwORG9ja2VyQnVpbGRlcjIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSs004yyVW4dEREZgTGbN1Dzbc ++VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCnSlHIpU6Ax7tP +WGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP+N8d1taRSrhR +vbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV+JsmCf6oPDt4 +b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqpibaQbG1UTX1f +5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7kxAdOC/KTAgMB +AAGjUzBRMB0GA1UdDgQWBBQ1oKojBf5qgkezUk6axrz3CjdHmzAfBgNVHSMEGDAW +gBQ1oKojBf5qgkezUk6axrz3CjdHmzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQCDUUOV23QzoqeGs7CKHXg+Mvxn6E4Tm395c0RKJRiHXEueQ2JD +e7ywfb11f/vGyudWVKe1wiRuMP4U8G6V3m6C/CSJrz1J3N9fvN23iPaZIh1O0vSr +xOz5UmiSsRW8BEQYCvF8CoWim1fG+KjtRhO6QqKLtK11j6TwZaUBIvSwK+OZKSuw +q8SuBRXNrIJvH0bonOXcuivOkruU0aRdizIG5Ed0OV2PVfbw2gu7Om83ADbVuSOV +noMwGjDVzVRAs8lu4ijuAryshVQK0LkImrwp+YkhRkFus0HWJqi/Ox+BHZt3BiFs +ATt9J3LCLazvP6LGr4rlZixJqM2ZC7dP0lOl +-----END CERTIFICATE----- diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.crt b/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.crt new file mode 100644 index 000000000..45861b02a --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRzCCAi+gAwIBAgIUZuRSLr7riMCDUFHVQKYQh/abmZQwDQYJKoZIhvcNAQEL +BQAwMjEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFzAVBgNVBAMMDkRvY2tlckJ1 +aWxkZXIyMCAXDTI0MDcyNDIxMDk0NloYDzMwMDQwOTI1MjEwOTQ2WjAyMRcwFQYK +CZImiZPyLGQBGRYHVGVtdXJpbjEXMBUGA1UEAwwORG9ja2VyQnVpbGRlcjIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSs004yyVW4dEREZgTGbN1Dzbc ++VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCnSlHIpU6Ax7tP +WGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP+N8d1taRSrhR +vbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV+JsmCf6oPDt4 +b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqpibaQbG1UTX1f +5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7kxAdOC/KTAgMB +AAGjUzBRMB0GA1UdDgQWBBQ1oKojBf5qgkezUk6axrz3CjdHmzAfBgNVHSMEGDAW +gBQ1oKojBf5qgkezUk6axrz3CjdHmzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQCDUUOV23QzoqeGs7CKHXg+Mvxn6E4Tm395c0RKJRiHXEueQ2JD +e7ywfb11f/vGyudWVKe1wiRuMP4U8G6V3m6C/CSJrz1J3N9fvN23iPaZIh1O0vSr +xOz5UmiSsRW8BEQYCvF8CoWim1fG+KjtRhO6QqKLtK11j6TwZaUBIvSwK+OZKSuw +q8SuBRXNrIJvH0bonOXcuivOkruU0aRdizIG5Ed0OV2PVfbw2gu7Om83ADbVuSOV +noMwGjDVzVRAs8lu4ijuAryshVQK0LkImrwp+YkhRkFus0HWJqi/Ox+BHZt3BiFs +ATt9J3LCLazvP6LGr4rlZixJqM2ZC7dP0lOl +-----END CERTIFICATE----- diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.key b/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.key new file mode 100644 index 000000000..b4fce7f80 --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs_symlink/.dockerbuilder2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDSs004yyVW4dER +EZgTGbN1Dzbc+VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCn +SlHIpU6Ax7tPWGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP ++N8d1taRSrhRvbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV ++JsmCf6oPDt4b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqp +ibaQbG1UTX1f5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7k +xAdOC/KTAgMBAAECggEAANIrB8nVtFbjVrmdnEqVs8drnITzVmYN+gxhaSTiQwuq +9dWyjY6+omPYVma94GKADlR7oXd+7cyLks65rrXRCdi0PaKw6vox9WdkMCY803zr +BWrouq0Hq1W0y3x3WOjrSyjOiTgdwhBDlLH1Vk/tV/VwybOa4dMeRKveFkNmbXKU +ZeR62r95vob4F5Ui6CWqSDRXFSml8VvBkU+6RAm697Lm5JQKoOuUueR9/L5z2Y0Z +rpGeBQ2tbbRIAvQWG3PhQirDqduL2e8aUs/RG8jGmbAnB9LoWJtaBEgLoza6221F +vboRWDLG5yZorXeGHT169+LQQ84rtwyjbQkvKjcP1QKBgQD632J17fWqK5cBaU2c +2bxAwS8aoqzPgBkAD2E8/VBEmJfjUAH5KVNuF9oeO/ho6JUOHoAWxMeu9v0ikynb +wnznQXlgieJCockJaTx1fkE/+W38uRXLK1TBSHFB7QdhPJbdeOh0jbsxNoX3wCAW +jQDUf2CoVdt+326II71IhDnnbQKBgQDXAbpkEWMYnWbl+WmSwGGud2AO7Uaw6ZQK +e83/zKQYcLsGHVMEJ41i2Lrd+VGJjK1eHUyOxHYg4Cel4cG5P7sU45yhehHVAeau +Z8KzQbB8BGcyMUoQFMIK5AXIiVdgTvt+aoKMEfXSAuZi1g5ATSS6zBoXWxlJyQ4b +R1MqOvMB/wKBgAw/3A7mD5i/iCAJhECkYQzIYgRq7QU0vAPEvHq94611xfTTc0U3 +P1ugzoWrZ/W3ZY/K7XYvJZDlfnaxuNmCJZclG0gbc3DNdYOAH/OctpLpGvW8E9RX +yUumveD6MeINk1A9FxyZzwoYH3J5bxeqyt+VWKLfjlgjkMIU/KkNy8YBAoGAbU2G +mTqxmyDh38YE4sMEpbIwVkZP6r5EMXQxDHrXbUlZ+sjLnFATM44kqZYG2pt2w2K3 +udisiRgLb+wuFOQOUpdH2Ft7V0NpJ36+X2zksJd4cu7VzQkQgILdYc5YajCc7+5r +wZOb2ZD52IMjqZLOOlxqYzc/yt/4WOvQnqZrRbcCgYBQopNwh9Hx9SBIHkkZkq1Z +iiPZl05khB/Vw76hABwjMillQd+nOJNf4kymIiOzfThEw/a4kam1zWvN0kq9Guu/ +YMvd73sqcudB5IWIjdqq0lKML2rcoBGqKGj5dFZt6Un/jqbi5nHeoMubrZkXUdG8 +PDtV2BTZDwmo+btPF//U5Q== +-----END PRIVATE KEY----- diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/.multi-cert.crt b/.test/tests/java-ca-certificates-update/certs_symlink/.multi-cert.crt new file mode 100644 index 000000000..66293f662 --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs_symlink/.multi-cert.crt @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUIfl8I/yasxlsTEc30PLLRuleiCswDQYJKoZIhvcNAQEL +BQAwMTEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFjAUBgNVBAMMDURvY2tlckJ1 +aWxkZXIwIBcNMjMwNjEyMTgyNDE1WhgPMzAwMzA4MTQxODI0MTVaMDExFzAVBgoJ +kiaJk/IsZAEZFgdUZW11cmluMRYwFAYDVQQDDA1Eb2NrZXJCdWlsZGVyMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArfOgmluNXEIE7BWvt7jGgdZW/y5s +N78FcpZdM8Z2FatvjJKvNmJ9OkkkOSNBhGKAWpHn19JMNdQ2nEmTHMetg0hiSqRI +hBceAY4lDfOzxAyZGGpVzL9U1B9mOrX5O3EedF5AVvl0NZVjEwswuGaUa3zZBAKy +Z5Vv/z8Lw2uYIs/dtw8lcpEAb78BZ8bAhhhl+X+tTGK8agibLGQJT9l/JxS3pXyw +me4YaKQQRgvuqOTEt+x+0aA5E2EUTOGq0Li+i1ranf6ou5Dz/Y6LtXwT/j2bf4ZR +w2YHpYZL54UEtMWES2KAjsZ3u4DCxUIEfW8EgxUIhcepIDP1h05A3fSiWQIDAQAB +o1MwUTAdBgNVHQ4EFgQUr0VirSzDQTuNgGjDxRkxPFrjUKcwHwYDVR0jBBgwFoAU +r0VirSzDQTuNgGjDxRkxPFrjUKcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQsFAAOCAQEAlo6ZSAIKSUWqRygyNg9oWuLGfWMW//dZjU1MKBYVpM4Mry/aMD5d +kMQj9hm+zXhNYN01yLh/cdPKCQ/r1KP6lmCtZHp50Xe8HEnIymRYx0KMAcqYLjnT +DXwCPqtWvJ1do65vVJRN70CuF8T1JNFhPdirrAiuU7bhGPABfnbek7yNkTYgUSdb +WpV/WOFPh9Dl24vNl1/Cti+pQThlCgHF/+dVndFHN9FOOG8k8ohYkLwL+ZzKfOiZ +CVWn2mWk2EhcuTlg/3zkXmwjfzFTdXMhS1sdfJNReaY/omJ91euxB0c8iYZV4wuU +ghx+GJ14nO7RJNHNX4k+BBPxy3f56+cYrg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDRzCCAi+gAwIBAgIUZuRSLr7riMCDUFHVQKYQh/abmZQwDQYJKoZIhvcNAQEL +BQAwMjEXMBUGCgmSJomT8ixkARkWB1RlbXVyaW4xFzAVBgNVBAMMDkRvY2tlckJ1 +aWxkZXIyMCAXDTI0MDcyNDIxMDk0NloYDzMwMDQwOTI1MjEwOTQ2WjAyMRcwFQYK +CZImiZPyLGQBGRYHVGVtdXJpbjEXMBUGA1UEAwwORG9ja2VyQnVpbGRlcjIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSs004yyVW4dEREZgTGbN1Dzbc ++VcRXUCfVCuiWFeT8a8oHZrbtNxCXD6whcGvLHsjszJKUCseDLCnSlHIpU6Ax7tP +WGsUhY6Zl8I+JzeB/8tYpyNRCLlm2Rp5Iv4oOX2btKYoUy+oFkWP+N8d1taRSrhR +vbPz+FwFSrtQwuT+grQP9yWO0qFrHL5Vjckg0BjELMYZ4rUx4KsV+JsmCf6oPDt4 +b+gnMoZebumKTJ53Ej/Kh0Z30s+UHR9WlbZ9KEyuBifgErw/USqpibaQbG1UTX1f +5LealeITduNWcXIAkQYHddCyt8YRtO9oVrxxVdFmCtU4qUHlov7kxAdOC/KTAgMB +AAGjUzBRMB0GA1UdDgQWBBQ1oKojBf5qgkezUk6axrz3CjdHmzAfBgNVHSMEGDAW +gBQ1oKojBf5qgkezUk6axrz3CjdHmzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQCDUUOV23QzoqeGs7CKHXg+Mvxn6E4Tm395c0RKJRiHXEueQ2JD +e7ywfb11f/vGyudWVKe1wiRuMP4U8G6V3m6C/CSJrz1J3N9fvN23iPaZIh1O0vSr +xOz5UmiSsRW8BEQYCvF8CoWim1fG+KjtRhO6QqKLtK11j6TwZaUBIvSwK+OZKSuw +q8SuBRXNrIJvH0bonOXcuivOkruU0aRdizIG5Ed0OV2PVfbw2gu7Om83ADbVuSOV +noMwGjDVzVRAs8lu4ijuAryshVQK0LkImrwp+YkhRkFus0HWJqi/Ox+BHZt3BiFs +ATt9J3LCLazvP6LGr4rlZixJqM2ZC7dP0lOl +-----END CERTIFICATE----- diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/README.md b/.test/tests/java-ca-certificates-update/certs_symlink/README.md index b408dfed4..c5feb7d34 100644 --- a/.test/tests/java-ca-certificates-update/certs_symlink/README.md +++ b/.test/tests/java-ca-certificates-update/certs_symlink/README.md @@ -1 +1,9 @@ -This certificate/key pair has been generated with `openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder" -keyout certs/dockerbuilder.key -out certs/dockerbuilder.crt` and is only used for testing +These certificate/key pairs has been generated with + +``` shell +$ openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder" -keyout certs/dockerbuilder.key -out certs/dockerbuilder.crt +$ openssl req -nodes -new -x509 -days 358000 -subj "/DC=Temurin/CN=DockerBuilder2" -keyout certs/dockerbuilder2.key -out certs/dockerbuilder2.crt +$ cat certs/dockerbuilder.crt certs/dockerbuilder2.crt > certs/multi-cert.crt +``` + + and are only used for testing diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/dockerbuilder.crt b/.test/tests/java-ca-certificates-update/certs_symlink/dockerbuilder.crt deleted file mode 120000 index ac571385a..000000000 --- a/.test/tests/java-ca-certificates-update/certs_symlink/dockerbuilder.crt +++ /dev/null @@ -1 +0,0 @@ -.dockerbuilder.crt \ No newline at end of file diff --git a/.test/tests/java-ca-certificates-update/certs_symlink/multi-cert.crt b/.test/tests/java-ca-certificates-update/certs_symlink/multi-cert.crt new file mode 120000 index 000000000..c1e90006e --- /dev/null +++ b/.test/tests/java-ca-certificates-update/certs_symlink/multi-cert.crt @@ -0,0 +1 @@ +.multi-cert.crt \ No newline at end of file diff --git a/.test/tests/java-ca-certificates-update/run.sh b/.test/tests/java-ca-certificates-update/run.sh index 7c883fa19..ca7f72d87 100755 --- a/.test/tests/java-ca-certificates-update/run.sh +++ b/.test/tests/java-ca-certificates-update/run.sh @@ -10,7 +10,7 @@ CMD1=date # CMD2 in each run is to check for the `dockerbuilder` certificate in the Java keystore. Entrypoint export $CACERT to # point to the Java keystore. -CMD2=(sh -c "keytool -list -keystore \$CACERT -storepass changeit -alias dockerbuilder") +CMD2=(sh -c "keytool -list -keystore \"\$JRE_CACERTS_PATH\" -storepass changeit -alias dockerbuilder && keytool -list -keystore \"\$JRE_CACERTS_PATH\" -storepass changeit -alias dockerbuilder2") # For a custom entrypoint test, we need to create a new image. This image will get cleaned up at the end of the script # by the `finish` trap function. diff --git a/11/jdk/alpine/Dockerfile b/11/jdk/alpine/Dockerfile index bf4eb235d..8443793f8 100644 --- a/11/jdk/alpine/Dockerfile +++ b/11/jdk/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/11/jdk/alpine/entrypoint.sh b/11/jdk/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jdk/alpine/entrypoint.sh +++ b/11/jdk/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jdk/ubi/ubi9-minimal/entrypoint.sh b/11/jdk/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/11/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jdk/ubuntu/focal/Dockerfile b/11/jdk/ubuntu/focal/Dockerfile index 0fd6632a2..ced4de72f 100644 --- a/11/jdk/ubuntu/focal/Dockerfile +++ b/11/jdk/ubuntu/focal/Dockerfile @@ -100,6 +100,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/11/jdk/ubuntu/focal/entrypoint.sh b/11/jdk/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jdk/ubuntu/focal/entrypoint.sh +++ b/11/jdk/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jdk/ubuntu/jammy/Dockerfile b/11/jdk/ubuntu/jammy/Dockerfile index 2ce1d1eed..6f5d50ba8 100644 --- a/11/jdk/ubuntu/jammy/Dockerfile +++ b/11/jdk/ubuntu/jammy/Dockerfile @@ -100,6 +100,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/11/jdk/ubuntu/jammy/entrypoint.sh b/11/jdk/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jdk/ubuntu/jammy/entrypoint.sh +++ b/11/jdk/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jdk/ubuntu/noble/Dockerfile b/11/jdk/ubuntu/noble/Dockerfile index 5aed1a755..6d9976623 100644 --- a/11/jdk/ubuntu/noble/Dockerfile +++ b/11/jdk/ubuntu/noble/Dockerfile @@ -100,6 +100,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/11/jdk/ubuntu/noble/entrypoint.sh b/11/jdk/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jdk/ubuntu/noble/entrypoint.sh +++ b/11/jdk/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jre/alpine/Dockerfile b/11/jre/alpine/Dockerfile index 99fa6f01e..c02f16c04 100644 --- a/11/jre/alpine/Dockerfile +++ b/11/jre/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/11/jre/alpine/entrypoint.sh b/11/jre/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jre/alpine/entrypoint.sh +++ b/11/jre/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jre/ubi/ubi9-minimal/entrypoint.sh b/11/jre/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/11/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jre/ubuntu/focal/Dockerfile b/11/jre/ubuntu/focal/Dockerfile index ff3320647..bbf2da35c 100644 --- a/11/jre/ubuntu/focal/Dockerfile +++ b/11/jre/ubuntu/focal/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/11/jre/ubuntu/focal/entrypoint.sh b/11/jre/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jre/ubuntu/focal/entrypoint.sh +++ b/11/jre/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jre/ubuntu/jammy/Dockerfile b/11/jre/ubuntu/jammy/Dockerfile index e92cc0dfa..e83a6b1cc 100644 --- a/11/jre/ubuntu/jammy/Dockerfile +++ b/11/jre/ubuntu/jammy/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/11/jre/ubuntu/jammy/entrypoint.sh b/11/jre/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jre/ubuntu/jammy/entrypoint.sh +++ b/11/jre/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/11/jre/ubuntu/noble/Dockerfile b/11/jre/ubuntu/noble/Dockerfile index d8136559c..823e6c30b 100644 --- a/11/jre/ubuntu/noble/Dockerfile +++ b/11/jre/ubuntu/noble/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/11/jre/ubuntu/noble/entrypoint.sh b/11/jre/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/11/jre/ubuntu/noble/entrypoint.sh +++ b/11/jre/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jdk/alpine/Dockerfile b/17/jdk/alpine/Dockerfile index 3a7300773..f351d299d 100644 --- a/17/jdk/alpine/Dockerfile +++ b/17/jdk/alpine/Dockerfile @@ -40,6 +40,11 @@ RUN set -eux; \ # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory binutils \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/17/jdk/alpine/entrypoint.sh b/17/jdk/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jdk/alpine/entrypoint.sh +++ b/17/jdk/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jdk/ubi/ubi9-minimal/entrypoint.sh b/17/jdk/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/17/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jdk/ubuntu/focal/Dockerfile b/17/jdk/ubuntu/focal/Dockerfile index 9f34b7052..669e7130a 100644 --- a/17/jdk/ubuntu/focal/Dockerfile +++ b/17/jdk/ubuntu/focal/Dockerfile @@ -103,6 +103,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/17/jdk/ubuntu/focal/entrypoint.sh b/17/jdk/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jdk/ubuntu/focal/entrypoint.sh +++ b/17/jdk/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jdk/ubuntu/jammy/Dockerfile b/17/jdk/ubuntu/jammy/Dockerfile index da35fe594..9cdf27770 100644 --- a/17/jdk/ubuntu/jammy/Dockerfile +++ b/17/jdk/ubuntu/jammy/Dockerfile @@ -103,6 +103,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/17/jdk/ubuntu/jammy/entrypoint.sh b/17/jdk/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jdk/ubuntu/jammy/entrypoint.sh +++ b/17/jdk/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jdk/ubuntu/noble/Dockerfile b/17/jdk/ubuntu/noble/Dockerfile index 7c87f71e8..ca0f958f3 100644 --- a/17/jdk/ubuntu/noble/Dockerfile +++ b/17/jdk/ubuntu/noble/Dockerfile @@ -103,6 +103,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/17/jdk/ubuntu/noble/entrypoint.sh b/17/jdk/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jdk/ubuntu/noble/entrypoint.sh +++ b/17/jdk/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jre/alpine/Dockerfile b/17/jre/alpine/Dockerfile index e00c143f0..29fc49a93 100644 --- a/17/jre/alpine/Dockerfile +++ b/17/jre/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/17/jre/alpine/entrypoint.sh b/17/jre/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jre/alpine/entrypoint.sh +++ b/17/jre/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jre/ubi/ubi9-minimal/entrypoint.sh b/17/jre/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/17/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jre/ubuntu/focal/Dockerfile b/17/jre/ubuntu/focal/Dockerfile index d67ab6daf..40c4b1b2a 100644 --- a/17/jre/ubuntu/focal/Dockerfile +++ b/17/jre/ubuntu/focal/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/17/jre/ubuntu/focal/entrypoint.sh b/17/jre/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jre/ubuntu/focal/entrypoint.sh +++ b/17/jre/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jre/ubuntu/jammy/Dockerfile b/17/jre/ubuntu/jammy/Dockerfile index 28a69e0b3..0411cbcdd 100644 --- a/17/jre/ubuntu/jammy/Dockerfile +++ b/17/jre/ubuntu/jammy/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/17/jre/ubuntu/jammy/entrypoint.sh b/17/jre/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jre/ubuntu/jammy/entrypoint.sh +++ b/17/jre/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/17/jre/ubuntu/noble/Dockerfile b/17/jre/ubuntu/noble/Dockerfile index fcf0b06d7..7e32e9ba1 100644 --- a/17/jre/ubuntu/noble/Dockerfile +++ b/17/jre/ubuntu/noble/Dockerfile @@ -98,4 +98,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/17/jre/ubuntu/noble/entrypoint.sh b/17/jre/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/17/jre/ubuntu/noble/entrypoint.sh +++ b/17/jre/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jdk/alpine/Dockerfile b/21/jdk/alpine/Dockerfile index eb7fcaf5e..c9f27519d 100644 --- a/21/jdk/alpine/Dockerfile +++ b/21/jdk/alpine/Dockerfile @@ -40,6 +40,11 @@ RUN set -eux; \ # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory binutils \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/21/jdk/alpine/entrypoint.sh b/21/jdk/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jdk/alpine/entrypoint.sh +++ b/21/jdk/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jdk/ubi/ubi9-minimal/entrypoint.sh b/21/jdk/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/21/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jdk/ubuntu/jammy/Dockerfile b/21/jdk/ubuntu/jammy/Dockerfile index e10c3ab6d..17732f4a6 100644 --- a/21/jdk/ubuntu/jammy/Dockerfile +++ b/21/jdk/ubuntu/jammy/Dockerfile @@ -99,6 +99,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/21/jdk/ubuntu/jammy/entrypoint.sh b/21/jdk/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jdk/ubuntu/jammy/entrypoint.sh +++ b/21/jdk/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jdk/ubuntu/noble/Dockerfile b/21/jdk/ubuntu/noble/Dockerfile index b0ff0b199..bc43e034a 100644 --- a/21/jdk/ubuntu/noble/Dockerfile +++ b/21/jdk/ubuntu/noble/Dockerfile @@ -99,6 +99,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/21/jdk/ubuntu/noble/entrypoint.sh b/21/jdk/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jdk/ubuntu/noble/entrypoint.sh +++ b/21/jdk/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jre/alpine/Dockerfile b/21/jre/alpine/Dockerfile index 92dccf3c0..4b59fbe16 100644 --- a/21/jre/alpine/Dockerfile +++ b/21/jre/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/21/jre/alpine/entrypoint.sh b/21/jre/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jre/alpine/entrypoint.sh +++ b/21/jre/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jre/ubi/ubi9-minimal/entrypoint.sh b/21/jre/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/21/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jre/ubuntu/jammy/Dockerfile b/21/jre/ubuntu/jammy/Dockerfile index a2cef09a1..c4e1bfff0 100644 --- a/21/jre/ubuntu/jammy/Dockerfile +++ b/21/jre/ubuntu/jammy/Dockerfile @@ -94,4 +94,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/21/jre/ubuntu/jammy/entrypoint.sh b/21/jre/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jre/ubuntu/jammy/entrypoint.sh +++ b/21/jre/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/21/jre/ubuntu/noble/Dockerfile b/21/jre/ubuntu/noble/Dockerfile index edbd1c4f5..bcdb398e6 100644 --- a/21/jre/ubuntu/noble/Dockerfile +++ b/21/jre/ubuntu/noble/Dockerfile @@ -94,4 +94,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/21/jre/ubuntu/noble/entrypoint.sh b/21/jre/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/21/jre/ubuntu/noble/entrypoint.sh +++ b/21/jre/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jdk/alpine/Dockerfile b/22/jdk/alpine/Dockerfile index 2e2348732..79f1b57b2 100644 --- a/22/jdk/alpine/Dockerfile +++ b/22/jdk/alpine/Dockerfile @@ -40,6 +40,11 @@ RUN set -eux; \ # Error: java.io.IOException: Cannot run program "objcopy": error=2, No such file or directory binutils \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/22/jdk/alpine/entrypoint.sh b/22/jdk/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jdk/alpine/entrypoint.sh +++ b/22/jdk/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jdk/ubi/ubi9-minimal/entrypoint.sh b/22/jdk/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/22/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jdk/ubuntu/jammy/Dockerfile b/22/jdk/ubuntu/jammy/Dockerfile index 01f834888..0a68998ba 100644 --- a/22/jdk/ubuntu/jammy/Dockerfile +++ b/22/jdk/ubuntu/jammy/Dockerfile @@ -97,6 +97,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/22/jdk/ubuntu/jammy/entrypoint.sh b/22/jdk/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jdk/ubuntu/jammy/entrypoint.sh +++ b/22/jdk/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jdk/ubuntu/noble/Dockerfile b/22/jdk/ubuntu/noble/Dockerfile index 9d76c1fe3..fa41d3d99 100644 --- a/22/jdk/ubuntu/noble/Dockerfile +++ b/22/jdk/ubuntu/noble/Dockerfile @@ -97,6 +97,6 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] CMD ["jshell"] diff --git a/22/jdk/ubuntu/noble/entrypoint.sh b/22/jdk/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jdk/ubuntu/noble/entrypoint.sh +++ b/22/jdk/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jre/alpine/Dockerfile b/22/jre/alpine/Dockerfile index 7b0d7eaba..01f77b4a4 100644 --- a/22/jre/alpine/Dockerfile +++ b/22/jre/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/22/jre/alpine/entrypoint.sh b/22/jre/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jre/alpine/entrypoint.sh +++ b/22/jre/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jre/ubi/ubi9-minimal/entrypoint.sh b/22/jre/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/22/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jre/ubuntu/jammy/Dockerfile b/22/jre/ubuntu/jammy/Dockerfile index 96a2dba5f..714892d7a 100644 --- a/22/jre/ubuntu/jammy/Dockerfile +++ b/22/jre/ubuntu/jammy/Dockerfile @@ -92,4 +92,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/22/jre/ubuntu/jammy/entrypoint.sh b/22/jre/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jre/ubuntu/jammy/entrypoint.sh +++ b/22/jre/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/22/jre/ubuntu/noble/Dockerfile b/22/jre/ubuntu/noble/Dockerfile index 87cf93ff0..65571a1a1 100644 --- a/22/jre/ubuntu/noble/Dockerfile +++ b/22/jre/ubuntu/noble/Dockerfile @@ -92,4 +92,4 @@ RUN set -eux; \ echo "java --version"; java --version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/22/jre/ubuntu/noble/entrypoint.sh b/22/jre/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/22/jre/ubuntu/noble/entrypoint.sh +++ b/22/jre/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jdk/alpine/Dockerfile b/8/jdk/alpine/Dockerfile index 3b1554259..2b79e9f3f 100644 --- a/8/jdk/alpine/Dockerfile +++ b/8/jdk/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/8/jdk/alpine/entrypoint.sh b/8/jdk/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jdk/alpine/entrypoint.sh +++ b/8/jdk/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jdk/ubi/ubi9-minimal/entrypoint.sh b/8/jdk/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/8/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jdk/ubuntu/focal/Dockerfile b/8/jdk/ubuntu/focal/Dockerfile index b7a1193a6..6a91f96f7 100644 --- a/8/jdk/ubuntu/focal/Dockerfile +++ b/8/jdk/ubuntu/focal/Dockerfile @@ -96,4 +96,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jdk/ubuntu/focal/entrypoint.sh b/8/jdk/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jdk/ubuntu/focal/entrypoint.sh +++ b/8/jdk/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jdk/ubuntu/jammy/Dockerfile b/8/jdk/ubuntu/jammy/Dockerfile index 1e2b6a2fa..a81eeb80f 100644 --- a/8/jdk/ubuntu/jammy/Dockerfile +++ b/8/jdk/ubuntu/jammy/Dockerfile @@ -96,4 +96,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jdk/ubuntu/jammy/entrypoint.sh b/8/jdk/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jdk/ubuntu/jammy/entrypoint.sh +++ b/8/jdk/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jdk/ubuntu/noble/Dockerfile b/8/jdk/ubuntu/noble/Dockerfile index 09e12fff4..e4aa7a51f 100644 --- a/8/jdk/ubuntu/noble/Dockerfile +++ b/8/jdk/ubuntu/noble/Dockerfile @@ -96,4 +96,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jdk/ubuntu/noble/entrypoint.sh b/8/jdk/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jdk/ubuntu/noble/entrypoint.sh +++ b/8/jdk/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jre/alpine/Dockerfile b/8/jre/alpine/Dockerfile index 5ef18634f..5e2245f9c 100644 --- a/8/jre/alpine/Dockerfile +++ b/8/jre/alpine/Dockerfile @@ -37,6 +37,11 @@ RUN set -eux; \ # locales ensures proper character encoding and locale-specific behaviors using en_US.UTF-8 musl-locales musl-locales-lang \ tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* diff --git a/8/jre/alpine/entrypoint.sh b/8/jre/alpine/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jre/alpine/entrypoint.sh +++ b/8/jre/alpine/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jre/ubi/ubi9-minimal/entrypoint.sh b/8/jre/ubi/ubi9-minimal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/8/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jre/ubuntu/focal/Dockerfile b/8/jre/ubuntu/focal/Dockerfile index 517ed3ffd..d3a1d52b6 100644 --- a/8/jre/ubuntu/focal/Dockerfile +++ b/8/jre/ubuntu/focal/Dockerfile @@ -95,4 +95,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jre/ubuntu/focal/entrypoint.sh b/8/jre/ubuntu/focal/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jre/ubuntu/focal/entrypoint.sh +++ b/8/jre/ubuntu/focal/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jre/ubuntu/jammy/Dockerfile b/8/jre/ubuntu/jammy/Dockerfile index 11859a4eb..88c175088 100644 --- a/8/jre/ubuntu/jammy/Dockerfile +++ b/8/jre/ubuntu/jammy/Dockerfile @@ -95,4 +95,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jre/ubuntu/jammy/entrypoint.sh b/8/jre/ubuntu/jammy/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jre/ubuntu/jammy/entrypoint.sh +++ b/8/jre/ubuntu/jammy/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/8/jre/ubuntu/noble/Dockerfile b/8/jre/ubuntu/noble/Dockerfile index af08eb57c..982b49743 100644 --- a/8/jre/ubuntu/noble/Dockerfile +++ b/8/jre/ubuntu/noble/Dockerfile @@ -95,4 +95,4 @@ RUN set -eux; \ echo "java -version"; java -version; \ echo "Complete." COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] +ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"] diff --git a/8/jre/ubuntu/noble/entrypoint.sh b/8/jre/ubuntu/noble/entrypoint.sh index 0a5c75c36..dcc51cd2b 100755 --- a/8/jre/ubuntu/noble/entrypoint.sh +++ b/8/jre/ubuntu/noble/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/config/hotspot.yml b/config/hotspot.yml index cea1224fb..8b47bc518 100644 --- a/config/hotspot.yml +++ b/config/hotspot.yml @@ -21,18 +21,27 @@ configurations: - directory: ubuntu/noble image: ubuntu:24.04 architectures: [aarch64, arm, ppc64le, s390x, x64] + # `bash` is required for Ubuntu-based images to correctly resolve + # environment variables.with.dots.in.them. + shebang: /bin/bash os: ubuntu - directory: ubuntu/jammy image: ubuntu:22.04 architectures: [aarch64, arm, ppc64le, s390x, x64] deprecated: 23 + # `bash` is required for Ubuntu-based images to correctly resolve + # environment variables.with.dots.in.them. + shebang: /bin/bash os: ubuntu - directory: ubuntu/focal architectures: [aarch64, arm, ppc64le, s390x, x64] image: ubuntu:20.04 deprecated: 20 + # `bash` is required for Ubuntu-based images to correctly resolve + # environment variables.with.dots.in.them. + shebang: /bin/bash os: ubuntu - directory: ubi/ubi9-minimal diff --git a/docker_templates/alpine-linux.Dockerfile.j2 b/docker_templates/alpine-linux.Dockerfile.j2 index 4dc73069b..41d379279 100644 --- a/docker_templates/alpine-linux.Dockerfile.j2 +++ b/docker_templates/alpine-linux.Dockerfile.j2 @@ -17,6 +17,11 @@ RUN set -eux; \ musl-locales musl-locales-lang \ {% include 'partials/binutils.j2' -%} tzdata \ + # Contains `csplit` used for splitting multiple certificates in one file to multiple files, since keytool can + # only import one at a time. + coreutils \ + # Needed to extract CN and generate aliases for certificates + openssl \ ; \ rm -rf /var/cache/apk/* @@ -27,4 +32,4 @@ ENV JAVA_VERSION {{ java_version }} {% include 'partials/version-check.j2' %} COPY entrypoint.sh /__cacert_entrypoint.sh ENTRYPOINT ["/__cacert_entrypoint.sh"] -{% include 'partials/jshell.j2' %} \ No newline at end of file +{% include 'partials/jshell.j2' %} diff --git a/docker_templates/entrypoint.sh b/docker_templates/entrypoint.sh old mode 100755 new mode 100644 index 0a5c75c36..dcc51cd2b --- a/docker_templates/entrypoint.sh +++ b/docker_templates/entrypoint.sh @@ -1,50 +1,70 @@ #!/usr/bin/env sh -# Converted to POSIX shell to avoid the need for bash in the image +# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get +# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but +# are supported by `sh` in some Linux flavours. set -e +TMPDIR=${TMPDIR:-/tmp} + # JDK truststore location -CACERT=$JAVA_HOME/lib/security/cacerts +JRE_CACERTS_PATH=$JAVA_HOME/lib/security/cacerts # JDK8 puts its JRE in a subdirectory if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + JRE_CACERTS_PATH=$JAVA_HOME/jre/lib/security/cacerts fi # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - if [ ! -w /tmp ]; then - echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + if [ ! -w "$TMPDIR" ]; then + echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore." exit 1 fi # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, # we'll use a temporary truststore. - if [ ! -w "$CACERT" ]; then + if [ ! -w "$JRE_CACERTS_PATH" ]; then # We cannot write to the JVM truststore, so we create a temporary one - CACERT_NEW=$(mktemp) - echo "Using a temporary truststore at $CACERT_NEW" - cp $CACERT $CACERT_NEW - CACERT=$CACERT_NEW + JRE_CACERTS_PATH_NEW=$(mktemp) + echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW" + cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW" + JRE_CACERTS_PATH=$JRE_CACERTS_PATH_NEW # If we use a custom truststore, we need to make sure that the JVM uses it - export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit" fi tmp_store=$(mktemp) # Copy full system CA store to a temporary location - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" > /dev/null # Add the system CA certificates to the JVM truststore. - keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt > /dev/null + + # Clean up the temporary truststore + rm -f "$tmp_store" # Import the additional certificate into JVM truststore for i in /certificates/*crt; do if [ ! -f "$i" ]; then continue fi - keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + tmp_dir=$(mktemp -d) + BASENAME=$(basename "$i" .crt) + + # We might have multiple certificates in the file. Split this file into single files. The reason is that + # `keytool` does not accept multi-certificate files + csplit -s -z -b %02d.crt -f "$tmp_dir/$BASENAME-" "$i" '/-----BEGIN CERTIFICATE-----/' '{*}' + + for crt in "$tmp_dir/$BASENAME"-*; do + # Create an alias for the certificate + ALIAS=$(openssl x509 -in "$crt" -noout -subject -nameopt -space_eq | sed -n 's/^.*CN=\([^,]*\).*$/\1/p') + + # Add the certificate to the JVM truststore + keytool -import -noprompt -alias "$ALIAS" -file "$crt" -keystore "$JRE_CACERTS_PATH" -storepass changeit >/dev/null + done done # Add additional certificates to the system CA store. This requires write permissions to several system @@ -68,12 +88,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # UBI - if which update-ca-trust >/dev/null; then + if command -v update-ca-trust >/dev/null; then update-ca-trust fi # Ubuntu/Alpine - if which update-ca-certificates >/dev/null; then + if command -v update-ca-certificates >/dev/null; then update-ca-certificates fi else @@ -84,6 +104,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then fi # Let's provide a variable with the correct path for tools that want or need to use it -export CACERT +export JRE_CACERTS_PATH exec "$@" diff --git a/docker_templates/ubuntu.Dockerfile.j2 b/docker_templates/ubuntu.Dockerfile.j2 index 05dac147a..a74e892a6 100644 --- a/docker_templates/ubuntu.Dockerfile.j2 +++ b/docker_templates/ubuntu.Dockerfile.j2 @@ -43,5 +43,5 @@ ENV JAVA_VERSION {{ java_version }} {% endif %} {% include 'partials/version-check.j2' %} COPY entrypoint.sh /__cacert_entrypoint.sh -ENTRYPOINT ["/__cacert_entrypoint.sh"] -{% include 'partials/jshell.j2' %} \ No newline at end of file +ENTRYPOINT ["{{ shebang }}", "/__cacert_entrypoint.sh"] +{% include 'partials/jshell.j2' %} diff --git a/generate_dockerfiles.py b/generate_dockerfiles.py index 3708c3ceb..ab4a3351c 100644 --- a/generate_dockerfiles.py +++ b/generate_dockerfiles.py @@ -74,6 +74,7 @@ def archHelper(arch, os_name): directory = configuration["directory"] architectures = configuration["architectures"] os_name = configuration["os"] + shebang = configuration.get("shebang", "") base_image = configuration["image"] deprecated = configuration.get("deprecated", None) versions = configuration.get( @@ -162,6 +163,7 @@ def archHelper(arch, os_name): arch_data=arch_data, os_family=os_family, os=os_name, + shebang=shebang, ) print("Writing Dockerfile to", output_directory)