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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ steps:
| `force-download` | Always download Java and replace any matching version in the tool cache. | `false` |
| `set-default` | Add Java to `PATH` and set `JAVA_HOME`. When `false`, only version-specific `JAVA_HOME_<major>_<arch>` variables are set. | `true` |
| `problem-matcher` | Register Java compiler and uncaught exception problem matchers. | `true` |
| `block-compromised-certs` | Add known compromised CA certificates to the installed JDK's blocked certificates list. See [Blocking compromised CA certificates](docs/advanced-usage.md#blocking-compromised-ca-certificates). | `true` |
| `verify-signature` | Verify downloaded Java package signatures when supported. Explicitly setting this to `true` makes verification failures fatal. | Distribution-dependent; see [Download integrity and signatures](#download-integrity-and-signatures) |
| `verify-signature-public-key` | One or more ASCII-armored GPG public keys used for signature verification. Concatenate multiple armored key blocks. Custom keys replace the bundled distribution keys. | |
| `token` | Token for fetching GitHub.com-hosted version manifests, useful on GitHub Enterprise Server when unauthenticated requests are rate-limited. | `${{ github.token }}` on GitHub.com; empty string on GHES |
Expand Down
118 changes: 118 additions & 0 deletions __tests__/blocked-certs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
import * as fs from 'fs';
import os from 'os';
import path from 'path';

const mockWarning = jest.fn<(...args: any[]) => any>();

jest.unstable_mockModule('@actions/core', () => ({
info: jest.fn(),
debug: jest.fn(),
warning: mockWarning
}));

const {blockCompromisedCertificates, COMPROMISED_CERT_FINGERPRINTS} =
await import('../src/blocked-certs.js');

describe('blockCompromisedCertificates', () => {
let javaHome: string;

const writeList = (relative: string, content: string): string => {
const file = path.join(javaHome, relative);
fs.mkdirSync(path.dirname(file), {recursive: true});
fs.writeFileSync(file, content);
return file;
};

const fingerprintsIn = (file: string): string[] =>
fs
.readFileSync(file, 'utf8')
.split('\n')
.filter(line => /^[0-9A-F]{64}$/.test(line));

beforeEach(() => {
javaHome = fs.mkdtempSync(path.join(os.tmpdir(), 'blocked-certs-'));
});

afterEach(() => {
fs.rmSync(javaHome, {recursive: true, force: true});
jest.resetAllMocks();
});

it('appends the fingerprints to lib/security/blocked.certs', () => {
const file = writeList(
'lib/security/blocked.certs',
'Algorithm=SHA-256\nAAAA'
);

blockCompromisedCertificates(javaHome);

const content = fs.readFileSync(file, 'utf8');
expect(content.startsWith('Algorithm=SHA-256\nAAAA\n')).toBe(true);
expect(fingerprintsIn(file)).toEqual([...COMPROMISED_CERT_FINGERPRINTS]);
expect(mockWarning).not.toHaveBeenCalled();
});

it('is idempotent', () => {
const file = writeList('lib/security/blocked.certs', 'Algorithm=SHA-256\n');

blockCompromisedCertificates(javaHome);
blockCompromisedCertificates(javaHome);

expect(fingerprintsIn(file)).toHaveLength(
COMPROMISED_CERT_FINGERPRINTS.length
);
});

it('only adds fingerprints that are missing', () => {
const file = writeList(
'lib/security/blocked.certs',
`Algorithm=SHA-256\n${COMPROMISED_CERT_FINGERPRINTS[0].toLowerCase()}\n`
);

blockCompromisedCertificates(javaHome);

expect(fingerprintsIn(file)).toEqual(
COMPROMISED_CERT_FINGERPRINTS.slice(1)
);
});

it('updates blacklisted.certs in both the JDK and bundled JRE of older JDKs', () => {
const jdk = writeList(
'lib/security/blacklisted.certs',
'Algorithm=SHA-256\n'
);
const jre = writeList(
'jre/lib/security/blacklisted.certs',
'Algorithm=SHA-256\n'
);

blockCompromisedCertificates(javaHome);

expect(fingerprintsIn(jdk)).toHaveLength(
COMPROMISED_CERT_FINGERPRINTS.length
);
expect(fingerprintsIn(jre)).toHaveLength(
COMPROMISED_CERT_FINGERPRINTS.length
);
});

it('warns and leaves the file alone when it does not use SHA-256', () => {
const file = writeList('lib/security/blocked.certs', 'Algorithm=SHA-1\n');

blockCompromisedCertificates(javaHome);

expect(fs.readFileSync(file, 'utf8')).toBe('Algorithm=SHA-1\n');
expect(mockWarning).toHaveBeenCalledWith(
expect.stringContaining('does not use SHA-256')
);
});

it('warns when no blocked certificates list exists', () => {
blockCompromisedCertificates(javaHome);

expect(mockWarning).toHaveBeenCalledWith(
expect.stringContaining('Could not find a blocked certificates list')
);
});
});
2 changes: 2 additions & 0 deletions __tests__/setup-java.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ describe('setup action orchestration', () => {
booleanInputs.set('check-latest', true);
booleanInputs.set('force-download', true);
booleanInputs.set('set-default', false);
booleanInputs.set('block-compromised-certs', false);
inputs.set('verify-signature-public-key', 'public-key');
(fs.readFileSync as jest.Mock).mockReturnValue(
Buffer.from('java=21.0.5-tem')
Expand Down Expand Up @@ -263,6 +264,7 @@ describe('setup action orchestration', () => {
forceDownload: true,
cacheJdk: false,
setDefault: false,
blockCompromisedCerts: false,
verifySignature: undefined,
verifySignaturePublicKey: 'public-key'
},
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ inputs:
description: 'Whether to register the Java problem matcher (compiler errors/warnings and uncaught exceptions). Set to "false" to disable annotations.'
required: false
default: true
block-compromised-certs:
description: 'Add the fingerprints of known compromised CA certificates to the installed JDK''s blocked certificates list, so TLS connections through those CAs are rejected. Set to "false" to leave the JDK''s list unchanged.'
required: false
default: true
outputs:
distribution:
description: 'Distribution of Java that has been installed'
Expand Down
3 changes: 2 additions & 1 deletion dist/cleanup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31040,7 +31040,7 @@ module.exports = {
/* harmony export */ gk: () => (/* binding */ INPUT_CACHE),
/* harmony export */ wG: () => (/* binding */ INPUT_JOB_STATUS)
/* harmony export */ });
/* unused harmony exports MACOS_JAVA_CONTENT_POSTFIX, INPUT_JAVA_VERSION, INPUT_JAVA_VERSION_FILE, INPUT_ARCHITECTURE, INPUT_JAVA_PACKAGE, INPUT_DISTRIBUTION, INPUT_JDK_FILE, INPUT_JDK_FILE_DEPRECATED, INPUT_CHECK_LATEST, INPUT_FORCE_DOWNLOAD, INPUT_SET_DEFAULT, INPUT_PROBLEM_MATCHER, INPUT_VERIFY_SIGNATURE, INPUT_VERIFY_SIGNATURE_PUBLIC_KEY, SIGNATURE_VERIFICATION_DOCUMENTATION_URL, SIGNATURE_VERIFICATION_FAILURE_HELP, INPUT_MVN_SERVER_CREDENTIALS, INPUT_MVN_SERVER_REPOSITORY_ORIGINS, INPUT_MVN_REPOSITORIES, INPUT_MVN_PLUGIN_REPOSITORIES, INPUT_MVN_REPOSITORIES_INCLUDE_CENTRAL, INPUT_MVN_REPOSITORIES_PRIORITIZE_CENTRAL, INPUT_SERVER_ID, INPUT_SERVER_USERNAME_ENV_VAR, INPUT_SERVER_PASSWORD_ENV_VAR, INPUT_SERVER_USERNAME_DEPRECATED, INPUT_SERVER_PASSWORD_DEPRECATED, INPUT_SETTINGS_PATH, INPUT_OVERWRITE_SETTINGS, INPUT_GPG_PRIVATE_KEY, INPUT_GPG_PASSPHRASE_ENV_VAR, INPUT_GPG_PASSPHRASE_DEPRECATED, INPUT_DEFAULT_SERVER_USERNAME, INPUT_DEFAULT_SERVER_PASSWORD, INPUT_DEFAULT_GPG_PRIVATE_KEY, INPUT_DEFAULT_GPG_PASSPHRASE, MAVEN_GPG_PASSPHRASE_DEFAULT_ENV, GPG_PASSPHRASE_PROFILE_ID, MAVEN_REPOSITORIES_PROFILE_ID, MAVEN_CENTRAL_REPOSITORY_ID, MAVEN_CENTRAL_REPOSITORY_URL, INPUT_CACHE_DEPENDENCY_PATH, INPUT_CACHE_PATH, M2_DIR, MVN_SETTINGS_FILE, MVN_TOOLCHAINS_FILE, INPUT_MVN_TOOLCHAIN_ID, INPUT_MVN_TOOLCHAIN_VENDOR, INPUT_SHOW_DOWNLOAD_PROGRESS, MAVEN_ARGS_ENV, MAVEN_NO_TRANSFER_PROGRESS_FLAG, MAVEN_NO_TRANSFER_PROGRESS_LONG_FLAG, DISTRIBUTIONS_ONLY_MAJOR_VERSION */
/* unused harmony exports MACOS_JAVA_CONTENT_POSTFIX, INPUT_JAVA_VERSION, INPUT_JAVA_VERSION_FILE, INPUT_ARCHITECTURE, INPUT_JAVA_PACKAGE, INPUT_DISTRIBUTION, INPUT_JDK_FILE, INPUT_JDK_FILE_DEPRECATED, INPUT_CHECK_LATEST, INPUT_FORCE_DOWNLOAD, INPUT_SET_DEFAULT, INPUT_PROBLEM_MATCHER, INPUT_BLOCK_COMPROMISED_CERTS, INPUT_VERIFY_SIGNATURE, INPUT_VERIFY_SIGNATURE_PUBLIC_KEY, SIGNATURE_VERIFICATION_DOCUMENTATION_URL, SIGNATURE_VERIFICATION_FAILURE_HELP, INPUT_MVN_SERVER_CREDENTIALS, INPUT_MVN_SERVER_REPOSITORY_ORIGINS, INPUT_MVN_REPOSITORIES, INPUT_MVN_PLUGIN_REPOSITORIES, INPUT_MVN_REPOSITORIES_INCLUDE_CENTRAL, INPUT_MVN_REPOSITORIES_PRIORITIZE_CENTRAL, INPUT_SERVER_ID, INPUT_SERVER_USERNAME_ENV_VAR, INPUT_SERVER_PASSWORD_ENV_VAR, INPUT_SERVER_USERNAME_DEPRECATED, INPUT_SERVER_PASSWORD_DEPRECATED, INPUT_SETTINGS_PATH, INPUT_OVERWRITE_SETTINGS, INPUT_GPG_PRIVATE_KEY, INPUT_GPG_PASSPHRASE_ENV_VAR, INPUT_GPG_PASSPHRASE_DEPRECATED, INPUT_DEFAULT_SERVER_USERNAME, INPUT_DEFAULT_SERVER_PASSWORD, INPUT_DEFAULT_GPG_PRIVATE_KEY, INPUT_DEFAULT_GPG_PASSPHRASE, MAVEN_GPG_PASSPHRASE_DEFAULT_ENV, GPG_PASSPHRASE_PROFILE_ID, MAVEN_REPOSITORIES_PROFILE_ID, MAVEN_CENTRAL_REPOSITORY_ID, MAVEN_CENTRAL_REPOSITORY_URL, INPUT_CACHE_DEPENDENCY_PATH, INPUT_CACHE_PATH, M2_DIR, MVN_SETTINGS_FILE, MVN_TOOLCHAINS_FILE, INPUT_MVN_TOOLCHAIN_ID, INPUT_MVN_TOOLCHAIN_VENDOR, INPUT_SHOW_DOWNLOAD_PROGRESS, MAVEN_ARGS_ENV, MAVEN_NO_TRANSFER_PROGRESS_FLAG, MAVEN_NO_TRANSFER_PROGRESS_LONG_FLAG, DISTRIBUTIONS_ONLY_MAJOR_VERSION */
const MACOS_JAVA_CONTENT_POSTFIX = 'Contents/Home';
const INPUT_JAVA_VERSION = 'java-version';
const INPUT_JAVA_VERSION_FILE = 'java-version-file';
Expand All @@ -31053,6 +31053,7 @@ const INPUT_CHECK_LATEST = 'check-latest';
const INPUT_FORCE_DOWNLOAD = 'force-download';
const INPUT_SET_DEFAULT = 'set-default';
const INPUT_PROBLEM_MATCHER = 'problem-matcher';
const INPUT_BLOCK_COMPROMISED_CERTS = 'block-compromised-certs';
const INPUT_VERIFY_SIGNATURE = 'verify-signature';
const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
const SIGNATURE_VERIFICATION_DOCUMENTATION_URL = 'https://github.com/actions/setup-java#download-integrity-and-signatures';
Expand Down
2 changes: 1 addition & 1 deletion dist/setup/126.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const modules = {
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6928);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4527);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(370);
/* harmony import */ var _platform_types_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7444);


Expand Down
2 changes: 1 addition & 1 deletion dist/setup/151.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const modules = {
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6928);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(370);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4527);


Expand Down
2 changes: 1 addition & 1 deletion dist/setup/182.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const modules = {
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6928);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(370);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4527);
/* harmony import */ var _actions_http_client__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4942);

Expand Down
2 changes: 1 addition & 1 deletion dist/setup/19.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const modules = {
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6928);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(370);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4527);
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7242);
/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6982);
Expand Down
4 changes: 2 additions & 2 deletions dist/setup/220.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ __webpack_require__.d(__webpack_exports__, {

// UNUSED EXPORTS: MICROSOFT_PUBLIC_KEY

// EXTERNAL MODULE: ./src/distributions/base-installer.ts + 2 modules
var base_installer = __webpack_require__(6242);
// EXTERNAL MODULE: ./src/distributions/base-installer.ts + 3 modules
var base_installer = __webpack_require__(370);
// EXTERNAL MODULE: ./src/util.ts
var util = __webpack_require__(4527);
// EXTERNAL MODULE: ./src/gpg.ts
Expand Down
2 changes: 1 addition & 1 deletion dist/setup/228.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const modules = {
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2088);
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(semver__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4527);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(370);
/* harmony import */ var _platform_types_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7444);


Expand Down
2 changes: 1 addition & 1 deletion dist/setup/282.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const modules = {
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2088);
/* harmony import */ var semver__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(semver__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6242);
/* harmony import */ var _base_installer_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(370);
/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4527);
/* harmony import */ var _actions_http_client__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4942);

Expand Down
Loading