java-topology/test/jdk/sun/security/provider/acvp/Launcher.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

212 lines
7.7 KiB
Java

/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.test.lib.artifacts.Artifact;
import jdk.test.lib.artifacts.ArtifactResolver;
import jdk.test.lib.json.JSONValue;
import jtreg.SkippedException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.security.Provider;
import java.security.Security;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/*
* @test
* @bug 8342442 8345057
* @summary Test default implementation. Use othervm because
* ML_DSA_Impls.version might be modified
* @library /test/lib
* @modules java.base/sun.security.provider
* java.base/sun.security.util
* java.base/com.sun.crypto.provider
* @run main/othervm/timeout=480 Launcher
*/
/*
* @test
* @bug 8342442 8345057
* @summary Test verifying the intrinsic implementation.
* @library /test/lib
* @modules java.base/sun.security.provider
* java.base/sun.security.util
* java.base/com.sun.crypto.provider
* @run main/othervm/timeout=480 -Xcomp Launcher
*/
/// This test runs on `internalProjection.json`-style files generated by NIST's
/// ACVP Server ([GitHub repository](https://github.com/usnistgov/ACVP-Server)).
/// These files are included in ZIP archives available under the
/// [tags section](https://github.com/usnistgov/ACVP-Server/tags)
/// of the repository.
///
/// The zip archive is either hosted on artifactory server or
/// specified with local path to the test.
/// The test looks for test data files in the archive listed with `TEST_FILES`.
///
/// These tests are currently compatible with ACVP version 1.1.0.38.
///
/// By default, the test uses system-preferred implementations.
/// If you want to test a specific provider, set the
/// `test.acvp.provider` test property. The provider must be
/// registered.
///
/// Tests for each algorithm must be compliant to its specification linked from
/// [https://github.com/usnistgov/ACVP?tab=readme-ov-file#supported-algorithms].
///
/// Example:
///
/// Run locally with ArtifactResolver
/// ```
/// jtreg -Djdk.test.lib.artifacts.ACVP-Server=<path-to-archive-file>
/// ```
/// OR host the zip archive on artifactory server.
///
public class Launcher {
private static final Provider PROVIDER;
private static final String ACVP_BUNDLE_LOC = "jpg.tests.jdk";
private static final String ACVP_BUNDLE_NAME = "ACVP-Server";
private static final String ACVP_BUNDLE_VERSION = "1.1.0.38";
// Zip archive entry name, do not update to use File.separator
private static final String[] TEST_FILES = {
"gen-val/json-files/ML-DSA-keyGen-FIPS204/internalProjection.json",
"gen-val/json-files/ML-DSA-sigGen-FIPS204/internalProjection.json",
"gen-val/json-files/ML-DSA-sigVer-FIPS204/internalProjection.json",
"gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json",
"gen-val/json-files/ML-KEM-keyGen-FIPS203/internalProjection.json"
};
private static int count = 0;
private static int invalidTest = 0;
private static int unsupportedTest = 0;
static {
var provProp = System.getProperty("test.acvp.provider");
if (provProp != null) {
var p = Security.getProvider(provProp);
if (p == null) {
System.err.println(provProp + " is not a registered provider name");
throw new RuntimeException(provProp + " is not a registered provider name");
}
PROVIDER = p;
} else {
PROVIDER = null;
}
}
public static void main(String[] args) throws Exception {
Path archivePath = null;
try {
archivePath = ArtifactResolver.fetchOne(ACVP_SERVER_TESTS.class);
} catch (IOException e) {
if (e.getMessage().contains("Cannot find the artifact ACVP-Server")) {
throw new SkippedException("ACVP-Server not available.");
}
}
System.out.println("Data path: " + archivePath);
if (PROVIDER != null) {
System.out.println("Provider: " + PROVIDER.getName());
}
// Read test data files from zip archive
try (ZipFile zf = new ZipFile(archivePath.toFile())) {
for (String testFile : TEST_FILES) {
// Zip archive entry name, do not update to use File.separator
String fullEntryName = ACVP_BUNDLE_NAME + "-" + ACVP_BUNDLE_VERSION + "/" + testFile;
System.out.println("Find and test with: " + fullEntryName);
ZipEntry ze = zf.getEntry(fullEntryName);
if (ze != null) {
run(zf.getInputStream(ze));
} else {
throw new RuntimeException("Entry not found: " + fullEntryName);
}
}
}
if (count > 0) {
System.out.println();
System.out.println("Test completed: " + count);
System.out.println("Invalid tests: " + invalidTest);
System.out.println("Unsupported tests: " + unsupportedTest);
} else {
throw new RuntimeException("No supported test found");
}
if (invalidTest != 0 || unsupportedTest != 0){
throw new RuntimeException("Invalid or Unsupported tests found");
}
}
static void run(InputStream test) {
try {
JSONValue kat;
try (test) {
kat = JSONValue.parse(new String(test.readAllBytes()));
} catch (Exception e) {
System.out.println("Warning: cannot parse " + test + ". Skipped");
invalidTest++;
return;
}
var alg = kat.get("algorithm").asString();
switch (alg) {
case "ML-DSA" -> {
ML_DSA_Test.run(kat, PROVIDER);
count++;
}
case "ML-KEM" -> {
ML_KEM_Test.run(kat, PROVIDER);
count++;
}
case "SHA2-256", "SHA2-224", "SHA3-256", "SHA3-224" -> {
SHA_Test.run(kat, PROVIDER);
count++;
}
default -> {
System.out.println("Skipped unsupported algorithm: " + alg);
unsupportedTest++;
}
}
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Artifact(
organization = ACVP_BUNDLE_LOC,
name = ACVP_BUNDLE_NAME,
revision = ACVP_BUNDLE_VERSION,
extension = "zip",
unpack = false)
private static class ACVP_SERVER_TESTS {
}
}