Skip to content
Commits on Source (69)
......@@ -32,6 +32,8 @@ matrix:
env: BASE_IMAGE="fedora_29_jdk11"
- stage: extra
env: BASE_IMAGE="fedora_rawhide"
- stage: extra
env: BASE_IMAGE="fedora_sandbox"
- stage: extra
env: BASE_IMAGE="fast_finish"
script:
......@@ -47,3 +49,5 @@ matrix:
env: BASE_IMAGE="fedora_29_jdk11"
- stage: extra
env: BASE_IMAGE="fedora_rawhide"
- stage: extra
env: BASE_IMAGE="fedora_sandbox"
......@@ -11,6 +11,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
# Define optional variables and conditionals.
if (DEFINED ENV{CHECK_DEPRECATION})
set(CHECK_DEPRECATION_ENV TRUE)
endif()
option(CHECK_DEPRECATION "When enabled, utilize the deprecation checking functionality of the java compiler." ${CHECK_DEPRECATION_ENV})
if (CHECK_DEPRECATION)
list(APPEND JSS_JAVAC_FLAGS "-Xlint:deprecation")
endif()
......@@ -19,6 +23,11 @@ if (DEFINED ENV{FIPS_ENABLED})
endif()
option(FIPS_ENABLED "When enabled, disable certain tests which don't work in FIPS mode. This should only be specified when the host system is in FIPS mode." ${FIPS_ENABLED_ENV})
if (DEFINED ENV{SANDBOX})
set(SANDBOX_ENV TRUE)
endif()
option(SANDBOX "When enabled, expect to find nss and nspr from the parent (sandbox) directory instead of using the system-installed versions of the libraries." ${SANDBOX_ENV})
# Build a debug build by default when no type is specified on the command line
if(NOT (DEFINED CMAKE_BUILD_TYPE))
set(CMAKE_BUILD_TYPE "Debug")
......@@ -33,9 +42,15 @@ find_package(NSS REQUIRED)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
# Shims for older CMake versions without useful features.
include(Shims)
# Since we found Java, include UseJava to provide the find_jar function.
include(UseJava)
# This include is required for the macro check_symbol_exists in jss_config()
include(CheckSymbolExists)
# Load JSSConfig module; this defines the jss_config() macro which defines
# JSS-specific configuration values.
include(JSSConfig)
......
......@@ -13,8 +13,22 @@
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (SANDBOX)
# Bypass the cache: we want to use files from the directory above.
set(NSS_FOUND TRUE)
if (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS)
# Read the internal build directory from the dist directory
set(DIST_DIR "${CMAKE_SOURCE_DIR}/../dist")
file(READ "${DIST_DIR}/latest" LATEST_BUILD)
string(STRIP "${LATEST_BUILD}" LATEST_BUILD)
message(STATUS "NSS sandbox build directory: ${LATEST_BUILD}")
# Directly set the NSS include and library directories
set(NSPR_INCLUDE_DIRS "${DIST_DIR}/${LATEST_BUILD}/include/nspr")
set(NSPR_LIBRARIES "${DIST_DIR}/${LATEST_BUILD}/lib")
list(APPEND JSS_LD_FLAGS "-Wl,-rpath,${DIST_DIR}/${LATEST_BUILD}/lib")
elseif (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS)
# in cache already
set(NSPR_FOUND TRUE)
else (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS)
......@@ -101,4 +115,4 @@ else (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS)
# show the NSPR_INCLUDE_DIRS and NSPR_LIBRARIES variables only in the advanced view
mark_as_advanced(NSPR_INCLUDE_DIRS NSPR_LIBRARIES)
endif (NSPR_LIBRARIES AND NSPR_INCLUDE_DIRS)
endif()
......@@ -13,8 +13,22 @@
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (SANDBOX)
# Bypass the cache: we want to use files from the directory above.
set(NSS_FOUND TRUE)
# Read the internal build directory from the dist directory
set(DIST_DIR "${CMAKE_SOURCE_DIR}/../dist")
file(READ "${DIST_DIR}/latest" LATEST_BUILD)
string(STRIP "${LATEST_BUILD}" LATEST_BUILD)
message(STATUS "NSS sandbox build directory: ${LATEST_BUILD}")
if (NSS_LIBRARIES AND NSS_INCLUDE_DIRS)
# Directly set the NSS include and library directories
set(NSS_INCLUDE_DIRS "${DIST_DIR}/public/nss")
set(NSS_LIBRARIES "${DIST_DIR}/${LATEST_BUILD}/lib")
list(APPEND JSS_LD_FLAGS "-Wl,-rpath,${DIST_DIR}/${LATEST_BUILD}/lib")
elseif (NSS_LIBRARIES AND NSS_INCLUDE_DIRS)
# in cache already
set(NSS_FOUND TRUE)
else (NSS_LIBRARIES AND NSS_INCLUDE_DIRS)
......@@ -119,4 +133,4 @@ else (NSS_LIBRARIES AND NSS_INCLUDE_DIRS)
# show the NSS_INCLUDE_DIRS and NSS_LIBRARIES variables only in the advanced view
mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES)
endif (NSS_LIBRARIES AND NSS_INCLUDE_DIRS)
endif()
......@@ -2,7 +2,7 @@ macro(jss_config)
# Set the current JSS release number. Arguments are:
# MAJOR MINOR PATCH BETA
# When BETA is zero, it isn't a beta release.
jss_config_version(4 6 1 0)
jss_config_version(4 6 2 0)
# Configure output directories
jss_config_outputs()
......@@ -13,6 +13,12 @@ macro(jss_config)
# Configure java-related flags
jss_config_java()
# Template auto-generated files
jss_config_template()
# Check symbols to see what tests we run
jss_config_symbols()
endmacro()
macro(jss_config_version MAJOR MINOR PATCH BETA)
......@@ -45,21 +51,11 @@ macro(jss_config_version MAJOR MINOR PATCH BETA)
set(JSS_VERSION "${JSS_VERSION} beta ${JSS_VERSION_BETA}")
set(JSS_VERSION_STR "${JSS_VERSION_STR}_b${JSS_VERSION_BETA}")
endif()
# Template files
configure_file(
"${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h.in"
"${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/lib/MANIFEST.MF.in"
"${CMAKE_BINARY_DIR}/MANIFEST.MF"
)
endmacro()
macro(jss_config_outputs)
# Global variables representing various output files; note that these are
# created at the end of this macro.
# Global variables representing various output files; note that these
# directories are created at the end of this macro.
set(CLASSES_OUTPUT_DIR "${CMAKE_BINARY_DIR}/classes/jss")
set(DOCS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/docs")
set(LIB_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib")
......@@ -104,9 +100,7 @@ macro(jss_config_outputs)
file(MAKE_DIRECTORY "${BIN_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${INCLUDE_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${JNI_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${TARGETS_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${TESTS_CLASSES_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${TESTS_INCLUDE_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${TESTS_JNI_OUTPUT_DIR}")
......@@ -134,12 +128,22 @@ macro(jss_config_cflags)
list(APPEND JSS_RAW_C_FLAGS "-Wno-unknown-warning-option")
list(APPEND JSS_RAW_C_FLAGS "-Werror-implicit-function-declaration")
list(APPEND JSS_RAW_C_FLAGS "-Wno-switch")
list(APPEND JSS_RAW_C_FLAGS "-I${NSPR_INCLUDE_DIR}")
list(APPEND JSS_RAW_C_FLAGS "-I${NSS_INCLUDE_DIR}")
list(APPEND JSS_RAW_C_FLAGS "-I${INCLUDE_OUTPUT_DIR}")
foreach(JNI_INCLUDE_DIR ${JNI_INCLUDE_DIRS})
list(APPEND JSS_RAW_C_FLAGS "-I${JNI_INCLUDE_DIR}")
endforeach()
foreach(NSPR_INCLUDE_DIR ${NSPR_INCLUDE_DIRS})
list(APPEND JSS_RAW_C_FLAGS "-I${NSPR_INCLUDE_DIR}")
endforeach()
foreach(NSS_INCLUDE_DIR ${NSS_INCLUDE_DIRS})
list(APPEND JSS_RAW_C_FLAGS "-I${NSS_INCLUDE_DIR}")
endforeach()
foreach(NSPR_LIBRARY ${NSPR_LIBRARIES})
list(APPEND JSS_RAW_C_FLAGS "-L${NSPR_LIBRARY}")
endforeach()
foreach(NSS_LIBRARY ${NSS_LIBRARIES})
list(APPEND JSS_RAW_C_FLAGS "-L${NSS_LIBRARY}")
endforeach()
foreach(JSS_RAW_C_FLAG ${JSS_RAW_C_FLAGS})
# Validate that each of our desired CFLAGS is supported by the
......@@ -306,6 +310,9 @@ macro(jss_config_java)
list(APPEND JSS_TEST_JAVAC_FLAGS "-O")
endif()
message(STATUS "JSS JAVAC FLAGS: ${JSS_JAVAC_FLAGS}")
message(STATUS "JSS TEST JAVAC FLAGS: ${JSS_TEST_JAVAC_FLAGS}")
# Variables for javadoc building. Note that JSS_PACKAGES needs to be
# updated whenever a new package is created.
set(JSS_WINDOW_TITLE "JSS: Java Security Services")
......@@ -315,3 +322,30 @@ macro(jss_config_java)
math(EXPR JSS_TEST_PORT_CLIENTAUTH ${JSS_BASE_PORT}+0)
math(EXPR JSS_TEST_PORT_CLIENTAUTH_FIPS ${JSS_BASE_PORT}+1)
endmacro()
macro(jss_config_template)
# Template files
configure_file(
"${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h.in"
"${PROJECT_SOURCE_DIR}/org/mozilla/jss/util/jssver.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/lib/MANIFEST.MF.in"
"${CMAKE_BINARY_DIR}/MANIFEST.MF"
)
configure_file(
"${PROJECT_SOURCE_DIR}/tools/run_test.sh.in"
"${CMAKE_BINARY_DIR}/run_test.sh"
)
endmacro()
macro(jss_config_symbols)
list(APPEND CMAKE_REQUIRED_INCLUDES ${NSPR_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
jss_list_join(JSS_C_FLAGS " " CMAKE_REQUIRED_FLAGS)
check_symbol_exists("CKM_AES_CMAC" "nspr.h;nss.h;pkcs11t.h" HAVE_NSS_CMAC)
if(NOT HAVE_NSS_CMAC)
message(WARNING "Your NSS version doesn't support CMAC; some features of JSS won't work.")
endif()
endmacro()
......@@ -22,6 +22,10 @@ macro(jss_tests)
COMMAND "cmake" "-E" "make_directory" "${RESULTS_DATA_OUTPUT_DIR}"
DEPENDS "Clean_Data_Dir"
)
jss_test_exec(
NAME "TestBufferPRFD"
COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFD"
)
# Rather than creating our results directories earlier in JSSConfig,
# create them here so that the test suite can be rerun multiple times.
......@@ -235,6 +239,16 @@ macro(jss_tests)
COMMAND "org.mozilla.jss.tests.JSSProvider" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}"
DEPENDS "List_CA_certs"
)
jss_test_java(
NAME "X509CertTest"
COMMAND "org.mozilla.jss.tests.X509CertTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}"
DEPENDS "List_CA_certs"
)
jss_test_java(
NAME "KeyStoreTest"
COMMAND "org.mozilla.jss.tests.KeyStoreTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}" getAliases
DEPENDS "List_CA_certs"
)
if(NOT FIPS_ENABLED)
jss_test_java(
......@@ -247,6 +261,13 @@ macro(jss_tests)
COMMAND "org.mozilla.jss.tests.HmacTest" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}"
DEPENDS "Setup_DBs"
)
if(HAVE_NSS_CMAC)
jss_test_java(
NAME "CMAC_Test"
COMMAND "org.mozilla.jss.tests.TestCmac" "${RESULTS_NSSDB_OUTPUT_DIR}" "${PASSWORD_FILE}"
DEPENDS "Setup_DBs"
)
endif()
jss_test_java(
NAME "Mozilla_JSS_Secret_Key_Generation"
COMMAND "org.mozilla.jss.tests.JCASymKeyGen" "${RESULTS_NSSDB_OUTPUT_DIR}"
......@@ -255,14 +276,14 @@ macro(jss_tests)
# SSL Engine related tests
jss_test_exec(
NAME "TestBufferPRFD_RSA"
COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFD" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_RSA"
DEPENDS "List_CA_certs" "generate_c_TestBufferPRFD"
NAME "TestBufferPRFDSSL_RSA"
COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_RSA"
DEPENDS "List_CA_certs" "generate_c_TestBufferPRFDSSL"
)
jss_test_exec(
NAME "TestBufferPRFD_ECDSA"
COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFD" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_ECDSA"
DEPENDS "List_CA_certs" "generate_c_TestBufferPRFD"
NAME "TestBufferPRFDSSL_ECDSA"
COMMAND "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "${RESULTS_NSSDB_OUTPUT_DIR}" "${DB_PWD}" "Server_ECDSA"
DEPENDS "List_CA_certs" "generate_c_TestBufferPRFDSSL"
)
jss_test_java(
NAME "JSS_Test_BufferPRFD"
......@@ -342,6 +363,7 @@ macro(jss_tests_compile)
jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/buffer_size_1.c" "${BIN_OUTPUT_DIR}/buffer_size_1" "buffer_size_1")
jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/buffer_size_4.c" "${BIN_OUTPUT_DIR}/buffer_size_4" "buffer_size_4")
jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/TestBufferPRFD.c" "${BIN_OUTPUT_DIR}/TestBufferPRFD" "TestBufferPRFD")
jss_tests_compile_c("${PROJECT_SOURCE_DIR}/org/mozilla/jss/tests/TestBufferPRFDSSL.c" "${BIN_OUTPUT_DIR}/TestBufferPRFDSSL" "TestBufferPRFDSSL")
endmacro()
macro(jss_tests_compile_c C_FILE C_OUTPUT C_TARGET)
......
# LIST(JOIN ...) was introduced in CMake verison 3.12
macro(jss_list_join LIST_ SEPARATOR_ VAR_)
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
set("${VAR_}" "")
foreach(ELEMENT ${${LIST_}})
message(STATUS "ELEM: ${ELEMENT}")
set("${VAR_}" "${${VAR_}}${SEPARATOR_}${ELEMENT}")
endforeach()
string(LENGTH "${SEPARATOR_}" JSS_LIST_JOIN_SEPARATOR_LENGTH)
string(SUBSTRING "${${VAR_}}" ${JSS_LIST_JOIN_SEPARATOR_LENGTH} -1 "${VAR_}")
else()
list(JOIN ${LIST_} ${SEPARATOR_} ${VAR_})
endif()
endmacro()
jss (4.6.2-1) unstable; urgency=medium
* New upstream release.
- fix CVE-2019-14823 (Closes: #942463)
* fix-bufferprfd.diff: Dropped, upstream.
-- Timo Aaltonen <tjaalton@debian.org> Thu, 17 Oct 2019 12:55:52 +0300
jss (4.6.1-3) unstable; urgency=medium
* use-release-8.diff: Set --release=8.
......
commit a272589d079eca9d3e056eeee386f30ef8cbc0f4
Author: Alexander Scheel <ascheel@redhat.com>
Date: Thu Aug 15 15:08:28 2019 -0400
Fix BufferPRFD's PRBufferGetSocketOption
PRBufferGetSocketOption takes two parameters: the PRFileDesc that we're
operating on and a PRSocketOptionData where we place the result. I
incorrectly treated this as a struct holding all options for a socket.
In reality, it contains two fields:
- the option requested
- the value of that option (via a union)
We thus need to condition on the option requested and return *only* its
value.
Under the previous implementation, we clobbered all options we set,
except the last one, data->value.send_buffer_size. In TestBufferPRFD.c,
we set the capacity of the buffer as 2048. Since sizeof(PRSize) >=
sizeof(PRBool), we did not perform an out of bounds write. On big endian
systems such as s390x, we stored the value 0x00000000 00000800: this
meant accessing data->value.non_blocking returned PR_FALSE (0x00).
Since the condition in ssl_FdIsBlocking is "!opt.value.non_blocking",
this resulted in NSS assuming our buffer was blocking.
Many thanks to Bob Relyea for finding this.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1730109
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
diff --git a/org/mozilla/jss/ssl/javax/BufferPRFD.c b/org/mozilla/jss/ssl/javax/BufferPRFD.c
index ba7206d4..7929f64d 100644
--- a/org/mozilla/jss/ssl/javax/BufferPRFD.c
+++ b/org/mozilla/jss/ssl/javax/BufferPRFD.c
@@ -189,34 +189,55 @@ static PRInt32 PRBufferRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn fl
// Fake responses to getSocketOption requests
static PRStatus PRBufferGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
{
- /* getSocketOption takes a PRFileDesc and modifies the PRSocketOptionData
- * with the options on this. We set a couple of sane defaults here:
+ /* getSocketOption takes a PRFileDesc and modifies the value field of data
+ * with socket option specified in the option field. We fake responses with
+ * a couple of sane defaults here:
*
* non_blocking = true
* reuse_addr = true
* keep_alive = false
* no_delay = true
*
- * However the list above is far fom extensive. Note that responses are
- * "fake" in that calls to setSocketOption fail to reflect here.
+ * We return valid responses to three other options:
+ *
+ * max_segment = capacity of read_buffer
+ * recv_buffer_size = capacity of read buffer
+ * send_buffer_size = capacity of write buffer
+ *
+ * Note that all responses are "fake" in that calls to SetSocketOption will
+ * not be reflected here.
*/
- if (data) {
- PRFilePrivate *internal = fd->secret;
+ if (!data || !fd) {
+ return PR_FAILURE;
+ }
+ PRFilePrivate *internal = fd->secret;
+ switch (data->option) {
+ case PR_SockOpt_Nonblocking:
data->value.non_blocking = PR_TRUE;
+ return PR_SUCCESS;
+ case PR_SockOpt_Reuseaddr:
data->value.reuse_addr = PR_TRUE;
+ return PR_SUCCESS;
+ case PR_SockOpt_Keepalive:
data->value.keep_alive = PR_FALSE;
- data->value.mcast_loopback = PR_FALSE;
+ return PR_SUCCESS;
+ case PR_SockOpt_NoDelay:
data->value.no_delay = PR_TRUE;
+ return PR_SUCCESS;
+ case PR_SockOpt_MaxSegment:
data->value.max_segment = jb_capacity(internal->read_buffer);
+ return PR_SUCCESS;
+ case PR_SockOpt_RecvBufferSize:
data->value.recv_buffer_size = jb_capacity(internal->read_buffer);
+ return PR_SUCCESS;
+ case PR_SockOpt_SendBufferSize:
data->value.send_buffer_size = jb_capacity(internal->write_buffer);
-
return PR_SUCCESS;
+ default:
+ return PR_FAILURE;
}
-
- return PR_FAILURE;
}
// Fake responses to setSocketOption
fix-bufferprfd.diff
use-release-8.diff
......@@ -46,12 +46,72 @@ of our project.
This directory contains two sets of files: dependencies and core modules.
The non-standard CMake dependencies currently include the `FindNSPR` and
FindNSS` modules: these allow CMake to find NSPR and NSS system libraries
`FindNSS` modules: these allow CMake to find NSPR and NSS system libraries
and were imported from PKI. The core modules include `JSSConfig`, which
sets useful variables for use within CMake, `JSSCommon`, which controls
building JSS, and `JSSTests`, which sets up the JSS test suite within
CTest.
### Available CMake Options
Our CMake generator currently understands the following options when
configuring the build system. Each option can either be specified on the CMake
command line with `-D<VAR>=<VALUE>` syntax, or in the environment.
- `CHECK_DEPRECATION` -- enable `-Xlint:deprecation` when compiling JSS to
check for use of deprecated APIs.
- `FIPS_ENABLED` -- disable certain test cases which are known to fail in
FIPS mode for various reasons. These usually include tests which try to
disable FIPS mode, use unsupported ciphers, or too small of key sizes.
Note that NSS must still be built with FIPS mode support enabled.
- `SANDBOX` -- support building sandboxed builds to test changes to NSPR or
NSS alongside changes to JSS. This assumes you have the following
directory structure:
```
sandbox/
sandbox/nspr
sandbox/nss
sandbox/dist
sandbox/jss
```
Note that `sandbox` can be replaced by any directory name. The
`sandbox/dist` folder is automatically created by NSS upon build.
Please first build NSS (according to current instructions) and then
build JSS.
### Adding a Test Case
To add a new test case, add an entry to `cmake/JSSTests.cmake`. There's two
useful helpers macros `jss_test_exec` and `jss_test_java`.
`jss_test_exec` takes a `NAME` parameter (to use to identify the test case
in output and when running particular tests), a `COMMAND` to execute, and an
optional set of dependencies (`DEPENDS ...`) on other tests. We use this
because `add_test` doesn't itself handle dependencies or set environment
variables (we need to inject `LD_LIBRARY_PATH` to handle testing our built
`libjss4.so`).
`jss_test_java` is a wrapper over `jss_test_exec` which handles setting up
the JVM and passing required arguments to it (`-classpath`, `-enableasserts`,
etc.). Pass only the class you wish to execute and any arguments to it as
the COMMAND field. (e.g., `COMMAND "org.mozilla.jss.tests.TestBuffer"`).
There are a few useful variables defined:
- `JSS_TEST_DIR` -- directory to the souce code where the tests are
contained.
- `PASSWORD_FILE` -- password for the NSS DB tokens.
- `DB_PWD` -- password for the NSS DB internal (default) token.
- `RESULTS_DATA_OUTPUT_DIR` -- directory to write test results to.
- `RESULTS_NSSDB_OUTPUT_DIR` -- path of the non-FIPS NSS DB.
- `RESULTS_NSSDB_FIPS_OUTPUT_DIR` -- path of the FIPS NSS DB.
Note that, on a FIPS-enabled machine, `RESULTS_NSSDB_FIPS_OUTPUT_DIR` is
unused and `RESULTS_NSSDB_OUTPUT_DIR` is actually placed in FIPS mode.
For tests which would fail in FIPS mode, place them in the
`if(NOT FIPS_ENABLED)` block.
## `lib/`
......
......@@ -6,7 +6,7 @@ Summary: Java Security Services (JSS)
URL: http://www.dogtagpki.org/wiki/JSS
License: MPLv1.1 or GPLv2+ or LGPLv2+
Version: 4.6.1
Version: 4.6.2
Release: 1%{?_timestamp}%{?_commit_id}%{?dist}
# global _phase -a1
......@@ -117,7 +117,7 @@ rm -rf build && mkdir -p build && cd build
..
%{__make} all
%{__make} javadoc || true
%{__make} javadoc
ctest --output-on-failure
################################################################################
......
......@@ -394,3 +394,12 @@ Java_org_mozilla_jss_nss_Buffer_Free;
local:
*;
};
JSS_4.6.2 {
global:
Java_org_mozilla_jss_pkcs11_PK11PrivKey_getPublicKey;
Java_org_mozilla_jss_CryptoManager_importDERCertNative;
Java_org_mozilla_jss_nss_SSL_AttachClientCertCallback;
Java_org_mozilla_jss_CryptoManager_getJSSDebug;
local:
*;
};
......@@ -12,6 +12,7 @@ import java.util.Iterator;
public final class CertificateUsage {
private int usage;
private int value;
private String name;
// certificateUsage, these must be kept in sync with nss/lib/certdb/certt.h
......@@ -28,18 +29,36 @@ public final class CertificateUsage {
private static final int certificateUsageProtectedObjectSigner = 0x0200;
private static final int certificateUsageStatusResponder = 0x0400;
private static final int certificateUsageAnyCA = 0x0800;
private static final int certificateUsageIPsec = 0x1000;
// SECCertUsage enum values
private static final int certUsageSSLClient = 0;
private static final int certUsageSSLServer = 1;
private static final int certUsageSSLServerWithStepUp = 2;
private static final int certUsageSSLCA = 3;
private static final int certUsageEmailSigner = 4;
private static final int certUsageEmailRecipient = 5;
private static final int certUsageObjectSigner = 6;
private static final int certUsageUserCertImport = 7;
private static final int certUsageVerifyCA = 8;
private static final int certUsageProtectedObjectSigner = 9;
private static final int certUsageStatusResponder = 10;
private static final int certUsageAnyCA = 11;
private static final int certUsageIPsec = 12;
static private ArrayList<CertificateUsage> list = new ArrayList<>();
private CertificateUsage() {
}
private CertificateUsage(int usage, String name) {
private CertificateUsage(int usage, int value, String name) {
this.usage = usage;
this.value = value;
this.name = name;
list.add(this);
}
public int getUsage() {
return usage;
}
......@@ -48,23 +67,29 @@ public final class CertificateUsage {
return list.iterator();
}
public String toString() {
return name;
}
public static final CertificateUsage CheckAllUsages = new CertificateUsage(certificateUsageCheckAllUsages, "CheckAllUsages");
public static final CertificateUsage SSLClient = new CertificateUsage(certificateUsageSSLClient, "SSLClient");
public static final CertificateUsage SSLServer = new CertificateUsage(certificateUsageSSLServer, "SSLServer");
public static final CertificateUsage SSLServerWithStepUp = new CertificateUsage(certificateUsageSSLServerWithStepUp, "SSLServerWithStepUp");
public static final CertificateUsage SSLCA = new CertificateUsage(certificateUsageSSLCA, "SSLCA");
public static final CertificateUsage EmailSigner = new CertificateUsage(certificateUsageEmailSigner, "EmailSigner");
public static final CertificateUsage EmailRecipient = new CertificateUsage(certificateUsageEmailRecipient, "EmailRecipient");
public static final CertificateUsage ObjectSigner = new CertificateUsage(certificateUsageObjectSigner, "ObjectSigner");
public static final CertificateUsage UserCertImport = new CertificateUsage(certificateUsageUserCertImport, "UserCertImport");
public static final CertificateUsage VerifyCA = new CertificateUsage(certificateUsageVerifyCA, "VerifyCA");
public static final CertificateUsage ProtectedObjectSigner = new CertificateUsage(certificateUsageProtectedObjectSigner, "ProtectedObjectSigner");
public static final CertificateUsage StatusResponder = new CertificateUsage(certificateUsageStatusResponder, "StatusResponder");
public static final CertificateUsage AnyCA = new CertificateUsage(certificateUsageAnyCA, "AnyCA");
public int getEnumValue() {
return value;
}
public static final CertificateUsage CheckAllUsages = new CertificateUsage(certificateUsageCheckAllUsages, -1, "CheckAllUsages");
public static final CertificateUsage SSLClient = new CertificateUsage(certificateUsageSSLClient, certUsageSSLClient, "SSLClient");
public static final CertificateUsage SSLServer = new CertificateUsage(certificateUsageSSLServer, certUsageSSLServer, "SSLServer");
public static final CertificateUsage SSLServerWithStepUp = new CertificateUsage(certificateUsageSSLServerWithStepUp, certUsageSSLServerWithStepUp, "SSLServerWithStepUp");
public static final CertificateUsage SSLCA = new CertificateUsage(certificateUsageSSLCA, certUsageSSLCA, "SSLCA");
public static final CertificateUsage EmailSigner = new CertificateUsage(certificateUsageEmailSigner, certUsageEmailSigner, "EmailSigner");
public static final CertificateUsage EmailRecipient = new CertificateUsage(certificateUsageEmailRecipient, certUsageEmailRecipient, "EmailRecipient");
public static final CertificateUsage ObjectSigner = new CertificateUsage(certificateUsageObjectSigner, certUsageObjectSigner, "ObjectSigner");
public static final CertificateUsage UserCertImport = new CertificateUsage(certificateUsageUserCertImport, certUsageUserCertImport, "UserCertImport");
public static final CertificateUsage VerifyCA = new CertificateUsage(certificateUsageVerifyCA, certUsageVerifyCA, "VerifyCA");
public static final CertificateUsage ProtectedObjectSigner = new CertificateUsage(certificateUsageProtectedObjectSigner, certUsageProtectedObjectSigner, "ProtectedObjectSigner");
public static final CertificateUsage StatusResponder = new CertificateUsage(certificateUsageStatusResponder, certUsageStatusResponder, "StatusResponder");
public static final CertificateUsage AnyCA = new CertificateUsage(certificateUsageAnyCA, certUsageAnyCA, "AnyCA");
public static final CertificateUsage IPsec = new CertificateUsage(certificateUsageIPsec, certUsageIPsec, "IPsec");
/*
The folllowing usages cannot be verified:
......
......@@ -904,7 +904,7 @@ Java_org_mozilla_jss_CryptoManager_enableFIPS
}
if(status != SECSuccess) {
JSS_throwMsg(env,
JSS_throwMsgPortErr(env,
GENERAL_SECURITY_EXCEPTION,
"Failed to toggle FIPS mode");
}
......@@ -1025,3 +1025,13 @@ Java_org_mozilla_jss_CryptoManager_getJSSPatchVersion(
return JSS_VPATCH;
}
JNIEXPORT jboolean JNICALL
Java_org_mozilla_jss_CryptoManager_getJSSDebug(JNIEnv *env, jobject this)
{
#ifdef DEBUG
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
......@@ -287,16 +287,16 @@ public final class CryptoManager implements TokenSupplier
while(tokens.hasMoreElements()) {
PK11Token token = (PK11Token) tokens.nextElement();
if( token.isInternalCryptoToken() ) {
Assert._assert(internalCryptoToken == null);
assert(internalCryptoToken == null);
internalCryptoToken = token;
}
if( token.isInternalKeyStorageToken() ) {
Assert._assert(internalKeyStorageToken == null);
assert(internalKeyStorageToken == null);
internalKeyStorageToken = token;
}
}
Assert._assert(internalKeyStorageToken != null);
Assert._assert(internalCryptoToken != null);
assert(internalKeyStorageToken != null);
assert(internalCryptoToken != null);
}
/**
......@@ -522,8 +522,12 @@ public final class CryptoManager implements TokenSupplier
logger.debug("Loaded " + kt);
if( values.installJSSProvider ) {
int position = java.security.Security.insertProviderAt(
new JSSProvider(), 1);
int insert_position = 1;
if (!values.installJSSProviderFirst) {
insert_position = java.security.Security.getProviders().length + 1;
}
int position = java.security.Security.insertProviderAt(new JSSProvider(), insert_position);
if (position < 0) {
logger.warn("JSS provider is already installed");
}
......@@ -737,6 +741,17 @@ public final class CryptoManager implements TokenSupplier
}
}
/**
* Imports a single DER-encoded certificate into the permanent or temporary
* certificate database.
*/
public X509Certificate importDERCert(byte[] cert, CertificateUsage usage,
boolean permanent, String nickname) {
return importDERCertNative(cert, usage.getEnumValue(), permanent, nickname);
}
private native X509Certificate importDERCertNative(byte[] cert, int usage, boolean permanent, String nickname);
private native InternalCertificate
importCertToPermNative(X509Certificate cert, String nickname)
throws TokenException;
......@@ -826,7 +841,7 @@ public final class CryptoManager implements TokenSupplier
findCertByNickname(String nickname)
throws ObjectNotFoundException, TokenException
{
Assert._assert(nickname!=null);
assert(nickname!=null);
return findCertByNicknameNative(nickname);
}
......@@ -842,7 +857,7 @@ public final class CryptoManager implements TokenSupplier
findCertsByNickname(String nickname)
throws TokenException
{
Assert._assert(nickname!=null);
assert(nickname!=null);
return findCertsByNicknameNative(nickname);
}
......@@ -934,7 +949,7 @@ public final class CryptoManager implements TokenSupplier
findPrivKeyByCert(org.mozilla.jss.crypto.X509Certificate cert)
throws ObjectNotFoundException, TokenException
{
Assert._assert(cert!=null);
assert(cert!=null);
if(! (cert instanceof org.mozilla.jss.pkcs11.PK11Cert)) {
throw new ObjectNotFoundException("Non-pkcs11 cert passed to PK11Finder");
}
......@@ -980,12 +995,15 @@ public final class CryptoManager implements TokenSupplier
public native static int getJSSMajorVersion();
public native static int getJSSMinorVersion();
public native static int getJSSPatchVersion();
private native static boolean getJSSDebug();
public static final String
JAR_JSS_VERSION = "JSS_VERSION = JSS_" + getJSSMajorVersion() +
"_" + getJSSMinorVersion() +
"_" + getJSSPatchVersion();
public static final boolean JSS_DEBUG = getJSSDebug();
// Hashtable is synchronized.
private Hashtable<Thread, CryptoToken> perThreadTokenTable = new Hashtable<>();
......@@ -1125,6 +1143,25 @@ public final class CryptoManager implements TokenSupplier
verifyCertificateNowNative2(nickname, checkSig, usage);
}
/**
* Verify an X509Certificate by checking if it's valid and that we trust
* the issuer. Verify time against now.
* @param cert the certificate to verify
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
public void verifyCertificate(X509Certificate cert, boolean checkSig,
CertificateUsage certificateUsage) throws ObjectNotFoundException,
InvalidNicknameException, CertificateException {
int usage = certificateUsage == null ? 0 : certificateUsage.getUsage();
verifyCertificateNowNative3(cert, checkSig, usage);
}
private native boolean verifyCertificateNowNative(String nickname,
boolean checkSig, int certificateUsage) throws ObjectNotFoundException;
......@@ -1134,6 +1171,12 @@ public final class CryptoManager implements TokenSupplier
int certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException;
private native void verifyCertificateNowNative3(
X509Certificate cert,
boolean checkSig,
int certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException;
/**
* note: this method calls obsolete function in NSS
*
......@@ -1225,6 +1268,17 @@ public final class CryptoManager implements TokenSupplier
return ocspPolicy.ordinal();
}
/**
* Gets the current OCSP Policy.
*
* @see getOCSPPolicy()
*
* @return - The current OCSP policy in effect.
*/
public static synchronized OCSPPolicy getOCSPPolicyEnum() {
return ocspPolicy;
}
/**
* Sets the current ocsp Policy.
* Currently we only support one mode OCSP_LEAF_AND_CHAIN_POLICY.
......
......@@ -401,6 +401,11 @@ public final class InitializationValues {
*/
public boolean removeSunProvider = false;
/**
* Whether or not to initialize the JSS provider first. Default is true.
*/
public boolean installJSSProviderFirst = true;
/**
* If <code>true</code>, none of the underlying NSS components will
* be initialized. Only the Java portions of JSS will be
......
......@@ -210,6 +210,12 @@ public final class JSSProvider extends java.security.Provider {
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA1");
put("SecretKeyFactory.PBAHmacSHA1",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBAHmacSHA1");
put("SecretKeyFactory.HmacSHA256",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA256");
put("SecretKeyFactory.HmacSHA384",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA384");
put("SecretKeyFactory.HmacSHA512",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA512");
put("SecretKeyFactory.PBEWithMD5AndDES",
"org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_MD5_DES_CBC");
put("SecretKeyFactory.PBEWithSHA1AndDES",
......@@ -235,11 +241,20 @@ public final class JSSProvider extends java.security.Provider {
put("Alg.Alias.Mac.Hmac-SHA384", "HmacSHA384");
put("Mac.HmacSHA512",
"org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA512");
put("Mac.CmacAES", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$CmacAES");
put("Alg.Alias.Mac.Hmac-SHA512", "HmacSHA512");
put("Alg.Alias.Mac.SHA-1-HMAC", "HmacSHA1");
put("Alg.Alias.Mac.SHA-256-HMAC", "HmacSHA256");
put("Alg.Alias.Mac.SHA-384-HMAC", "HmacSHA384");
put("Alg.Alias.Mac.SHA-512-HMAC", "HmacSHA512");
put("Alg.Alias.Mac.AES-128-CMAC", "CmacAES");
put("Alg.Alias.Mac.AES-192-CMAC", "CmacAES");
put("Alg.Alias.Mac.AES-256-CMAC", "CmacAES");
put("Alg.Alias.Mac.CmacAES128", "CmacAES");
put("Alg.Alias.Mac.CmacAES192", "CmacAES");
put("Alg.Alias.Mac.CmacAES256", "CmacAES");
put("Alg.Alias.Mac.AES_CMAC", "CmacAES");
put("Alg.Alias.Mac.CMAC_AES", "CmacAES");
/////////////////////////////////////////////////////////////
......
......@@ -32,6 +32,13 @@ JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage);
/*
* This is a private function, used only by JSS in this file.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative3(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage);
/*****************************************************************
*
* CryptoManager. f i n d C e r t B y N i c k n a m e N a t i v e
......@@ -1704,55 +1711,15 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative(JNIEnv *env,
return currUsage;
}
/***********************************************************************
* CryptoManager.verifyCertificateNowNative2
*
* Verify a certificate that exists in the given cert database,
* check if it's valid and that we trust the issuer. Verify time
* against now.
* @param nickname nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage)
void JSS_VerifyCertificate(JNIEnv *env, CERTCertificate *cert, jboolean checkSig,
jint usage)
{
jint certificateUsage;
SECCertificateUsage currUsage = 0x0000; /* unexposed for now */
SECStatus rv = SECFailure;
CERTCertificate *cert = NULL;
const char *nickname = NULL;
if (nickString == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}
int ocspPolicy = JSSL_getOCSPPolicy();
nickname = JSS_RefJString(env, nickString);
if (nickname == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}
certificateUsage = required_certificateUsage;
cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname);
if (cert == NULL) {
char *msgBuf;
msgBuf = PR_smprintf("Certificate not found: %s", nickname);
JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf);
PR_Free(msgBuf);
goto finish;
}
certificateUsage = usage;
/* 0 for certificateUsage in call to CERT_VerifyCertificateNow will
* retrieve the current valid usage into currUsage
......@@ -1779,7 +1746,7 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
if (rv != SECSuccess) {
JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Invalid certificate");
goto finish;
return;
}
if ((certificateUsage == 0x0000) &&
......@@ -1799,14 +1766,73 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
*/
JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Unusable certificate");
return;
}
}
/***********************************************************************
* CryptoManager.verifyCertificateNowNative2
*
* Verify a certificate that exists in the given cert database,
* check if it's valid and that we trust the issuer. Verify time
* against now.
* @param nickname nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage)
{
CERTCertificate *cert = NULL;
const char *nickname = NULL;
if (nickString == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}
nickname = JSS_RefJString(env, nickString);
if (nickname == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}
cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname);
if (cert == NULL) {
char *msgBuf;
msgBuf = PR_smprintf("Certificate not found: %s", nickname);
JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf);
PR_Free(msgBuf);
goto finish;
}
JSS_VerifyCertificate(env, cert, checkSig, required_certificateUsage);
finish:
JSS_DerefJString(env, nickString, nickname);
if (cert != NULL) {
CERT_DestroyCertificate(cert);
}
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative3(JNIEnv *env,
jobject self, jobject Cert, jboolean checkSig, jint required_certificateUsage)
{
CERTCertificate *cert = NULL;
if (JSS_PK11_getCertPtr(env, Cert, &cert) != PR_SUCCESS) {
PR_ASSERT((*env)->ExceptionOccurred(env) != NULL);
return;
}
JSS_VerifyCertificate(env, cert, checkSig, required_certificateUsage);
}
......@@ -1924,3 +1950,47 @@ Java_org_mozilla_jss_CryptoManager_verifyCertTempNative(JNIEnv *env,
}
}
/***********************************************************************
* CryptoManager.importDERCertNative
*/
JNIEXPORT jobject JNICALL
Java_org_mozilla_jss_CryptoManager_importDERCertNative(JNIEnv *env,
jobject self, jbyteArray cert, int usage, jboolean permanent,
jstring nickname)
{
char *nickname_raw = NULL;
jsize derCertLen;
SECItem *derCert = calloc(1, sizeof(SECItem));
CERTCertificate **retCert = NULL;
PR_ASSERT(env != NULL &&& self != NULL);
if (cert == NULL) {
return NULL;
}
if (nickname != NULL) {
nickname_raw = (char *)JSS_RefJString(env, nickname);
}
derCert->type = siDERCertBuffer;
if (!JSS_RefByteArray(env, cert, (signed char **)&derCert->data, &derCertLen)) {
return NULL;
}
PR_ASSERT(derCertLen > 0);
derCert->len = (unsigned int)derCertLen;
/* At the time of writing, caOnly is an unused parameter. */
if (CERT_ImportCerts(CERT_GetDefaultCertDB(), usage, 1, &derCert, &retCert,
permanent, PR_FALSE, nickname_raw) != SECSuccess) {
JSS_DerefByteArray(env, cert, derCert->data, JNI_ABORT);
JSS_DerefJString(env, nickname, nickname_raw);
JSS_throwMsgPortErr(env, INVALID_PARAMETER_EXCEPTION, "Unable to import certificate");
return NULL;
}
JSS_DerefByteArray(env, cert, derCert->data, JNI_ABORT);
JSS_DerefJString(env, nickname, nickname_raw);
return JSS_PK11_wrapCert(env, retCert);
}
......@@ -192,7 +192,7 @@ public class ANY implements ASN1Value {
{
byte[] contents = getContents();
ASN1Header oldHead = getHeader();
Assert._assert( contents.length == oldHead.getContentLength() );
assert( contents.length == oldHead.getContentLength() );
ASN1Header newHead = new ASN1Header( alternateTag, oldHead.getForm(),
contents.length);
......