diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d0656a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/jss-4.4.7.tar.gz diff --git a/.jss.metadata b/.jss.metadata new file mode 100644 index 0000000..9b6805b --- /dev/null +++ b/.jss.metadata @@ -0,0 +1 @@ +73cfcfdf2eefc39351b4b1dd9ee6f517faa64f19 SOURCES/jss-4.4.7.tar.gz diff --git a/SOURCES/0001-JSS-CVE-2019-14823-fix.patch b/SOURCES/0001-JSS-CVE-2019-14823-fix.patch new file mode 100644 index 0000000..46d1e4e --- /dev/null +++ b/SOURCES/0001-JSS-CVE-2019-14823-fix.patch @@ -0,0 +1,346 @@ +From 4c44f138e67db9c583baf78c7aa0460a941e9842 Mon Sep 17 00:00:00 2001 +From: Alexander Scheel +Date: Wed, 4 Sep 2019 08:33:14 -0400 +Subject: [PATCH] Fix root certificate validation + +When the Leaf and Chain OCSP checking policy is enabled in +CryptoManager, JSS will switch to alternative certificate verification +logic in JSSL_DefaultCertAuthCallback. In this method, the root +certificate was incorrectly trusted without being verified to exist in +the trust store. + +This patch cleans up the logic in JSSL_verifyCertPKIX and makes it +more explicit in addition to fixing the error. + +Fixes CVE-2019-14823 + +Signed-off-by: Alexander Scheel +--- + org/mozilla/jss/ssl/common.c | 239 ++++++++++++++++++++--------------- + 1 file changed, 136 insertions(+), 103 deletions(-) + +diff --git a/org/mozilla/jss/ssl/common.c b/org/mozilla/jss/ssl/common.c +index cd4d4425..3a448c54 100644 +--- a/org/mozilla/jss/ssl/common.c ++++ b/org/mozilla/jss/ssl/common.c +@@ -901,7 +901,6 @@ finish: + } + + /* Get the trusted anchor for pkix */ +- + CERTCertificate *getRoot(CERTCertificate *cert, + SECCertUsage certUsage) + { +@@ -935,79 +934,84 @@ finish: + return root; + } + +-/* Verify a cert using explicit PKIX call. +- * For now only used in OCSP AIA context. +- * The result of this call will be a full chain +- * and leaf network AIA ocsp validation. +- * The policy param will be used in the future to +- * handle more scenarios. +- */ +- +-SECStatus JSSL_verifyCertPKIX(CERTCertificate *cert, +- SECCertificateUsage certificateUsage,secuPWData *pwdata, int ocspPolicy, +- CERTVerifyLog *log, SECCertificateUsage *usage) ++/* Internal helper for the below call. */ ++static SECStatus ++JSSL_verifyCertPKIXInternal(CERTCertificate *cert, ++ SECCertificateUsage certificateUsage, secuPWData *pwdata, int ocspPolicy, ++ CERTVerifyLog *log, SECCertificateUsage *usage, ++ CERTCertList *trustedCertList) + { +- +- /* put the first set of possible flags internally here first */ +- /* later there could be a more complete list to choose from */ +- /* support our hard core fetch aia ocsp policy for now */ +- +- static PRUint64 ocsp_Enabled_Hard_Policy_LeafFlags[2] = { ++ /* Put the first set of possible flags internally here first. Later ++ * there could be a more complete list to choose from; for now we only ++ * support our hard core fetch AIA OCSP policy. Note that we disable ++ * CRL fetching as Dogtag doesn't support it. Additionally, enable OCSP ++ * checking on the chained CA certificates. Since NSS/PKIX's ++ * CERT_GetClassicOCSPEnabledHardFailurePolicy doesn't do what we want, ++ * we construct the policy ourselves. */ ++ PRUint64 ocsp_Enabled_Hard_Policy_LeafFlags[2] = { + /* crl */ +- 0, ++ CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD, + /* ocsp */ + CERT_REV_M_TEST_USING_THIS_METHOD | +- CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO ++ CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO + }; + +- static PRUint64 ocsp_Enabled_Hard_Policy_ChainFlags[2] = { ++ PRUint64 ocsp_Enabled_Hard_Policy_ChainFlags[2] = { + /* crl */ +- 0, ++ CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD, + /* ocsp */ + CERT_REV_M_TEST_USING_THIS_METHOD | +- CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO ++ CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO + }; + +- static CERTRevocationMethodIndex +- ocsp_Enabled_Hard_Policy_Method_Preference = { +- cert_revocation_method_ocsp +- }; +- +- static CERTRevocationFlags ocsp_Enabled_Hard_Policy = { +- { /* leafTests */ +- 2, +- ocsp_Enabled_Hard_Policy_LeafFlags, +- 1, +- &ocsp_Enabled_Hard_Policy_Method_Preference, +- 0 }, +- { /* chainTests */ +- 2, +- ocsp_Enabled_Hard_Policy_ChainFlags, +- 1, +- &ocsp_Enabled_Hard_Policy_Method_Preference, +- 0 } ++ CERTRevocationMethodIndex ocsp_Enabled_Hard_Policy_Method_Preference[1] = { ++ cert_revocation_method_ocsp + }; + +- /* for future expansion */ ++ CERTRevocationFlags ocsp_Enabled_Hard_Policy = { ++ /* CERTRevocationTests - leafTests */ ++ { ++ /* number_of_defined_methods */ ++ 2, ++ /* cert_rev_flags_per_method */ ++ ocsp_Enabled_Hard_Policy_LeafFlags, ++ /* number_of_preferred_methods */ ++ 1, ++ /* preferred_methods */ ++ ocsp_Enabled_Hard_Policy_Method_Preference, ++ /* cert_rev_method_independent_flags */ ++ 0 ++ }, ++ /* CERTRevocationTests - chainTests */ ++ { ++ /* number_of_defined_methods */ ++ 2, ++ /* cert_rev_flags_per_method */ ++ ocsp_Enabled_Hard_Policy_ChainFlags, ++ /* number_of_preferred_methods */ ++ 1, ++ /* preferred_methods */ ++ ocsp_Enabled_Hard_Policy_Method_Preference, ++ /* cert_rev_method_independent_flags */ ++ 0 ++ } ++ }; + +- CERTValOutParam cvout[20] = {0}; +- CERTValInParam cvin[20] = {0}; ++ /* The size of these objects are defined here based upon maximum possible ++ * inputs. A dynamic allocation could reallocate based upon actual usage, ++ * however this would affect the size by at most one or two. Note that, ++ * due to the required usage of cert_pi_end/cert_po_end, these sizes are ++ * inflated by one. */ ++ CERTValOutParam cvout[3] = {{0}}; ++ CERTValInParam cvin[6] = {{0}}; + ++ int usageIndex = -1; + int inParamIndex = 0; + int outParamIndex = 0; +- CERTRevocationFlags *rev = NULL; +- +- CERTCertList *trustedCertList = NULL; +- +- PRBool fetchCerts = PR_FALSE; + +- SECCertUsage certUsage = certUsageSSLClient /* 0 */; +- + SECStatus res = SECFailure; + +- CERTCertificate *root = NULL; +- +- if(cert == NULL) { ++ if (cert == NULL) { + goto finish; + } + +@@ -1015,93 +1019,122 @@ SECStatus JSSL_verifyCertPKIX(CERTCertificate *cert, + goto finish; + } + +- /* Force the strict ocsp network check on chain +- and leaf. +- */ +- +- fetchCerts = PR_TRUE; +- rev = &ocsp_Enabled_Hard_Policy; +- +- /* fetch aia over net */ +- ++ /* Enable live AIA fetching over the network. */ + cvin[inParamIndex].type = cert_pi_useAIACertFetch; +- cvin[inParamIndex].value.scalar.b = fetchCerts; +- inParamIndex++; +- +- /* time */ ++ cvin[inParamIndex].value.scalar.b = PR_TRUE; ++ inParamIndex++; + ++ /* By setting the time to zero, we choose the current time when the ++ * check is performed. */ + cvin[inParamIndex].type = cert_pi_date; +- cvin[inParamIndex].value.scalar.time = PR_Now(); ++ cvin[inParamIndex].value.scalar.time = 0; + inParamIndex++; + +- /* flags */ +- ++ /* Force the strict OCSP check on both the leaf and its chain. */ + cvin[inParamIndex].type = cert_pi_revocationFlags; +- cvin[inParamIndex].value.pointer.revocation = rev; ++ cvin[inParamIndex].value.pointer.revocation = &ocsp_Enabled_Hard_Policy; + inParamIndex++; + +- /* establish trust anchor */ +- +- /* We need to convert the SECCertificateUsage to a SECCertUsage to obtain +- * the root. +- */ +- +- SECCertificateUsage testUsage = certificateUsage; +- while (0 != (testUsage = testUsage >> 1)) { certUsage++; } +- +- root = getRoot(cert,certUsage); +- +- /* Try to add the root as the trust anchor so all the +- other memebers of the ca chain will get validated. +- */ +- +- if( root != NULL ) { +- trustedCertList = CERT_NewCertList(); +- CERT_AddCertToListTail(trustedCertList, root); +- ++ /* Establish a trust anchor if it is passed to us. NOTE: this trust anchor ++ * must previously be validated before it is passed to us here. */ ++ if (trustedCertList != NULL) { + cvin[inParamIndex].type = cert_pi_trustAnchors; + cvin[inParamIndex].value.pointer.chain = trustedCertList; +- + inParamIndex++; + } + ++ /* Done establishing input parameters. */ + cvin[inParamIndex].type = cert_pi_end; + +- if(log != NULL) { ++ /* When we need to log rationale for failure, pass it as an output ++ * parameter. */ ++ if (log != NULL) { + cvout[outParamIndex].type = cert_po_errorLog; + cvout[outParamIndex].value.pointer.log = log; + outParamIndex ++; + } + +- int usageIndex = 0; +- if(usage != NULL) { ++ /* When we need to inquire about the resulting certificate usage, pass it ++ * here. */ ++ if (usage != NULL) { + usageIndex = outParamIndex; + cvout[outParamIndex].type = cert_po_usages; + cvout[outParamIndex].value.scalar.usages = 0; + outParamIndex ++; + } + ++ /* Done establishing output parameters. */ + cvout[outParamIndex].type = cert_po_end; + ++ /* Call into NSS's PKIX library to validate our certificate. */ + res = CERT_PKIXVerifyCert(cert, certificateUsage, cvin, cvout, &pwdata); + + finish: +- /* clean up any trusted cert list */ +- ++ /* Clean up any certificates in the trusted certificate list. This was ++ * a passed input parameter, but by taking ownership of it and clearing it, ++ * we enable tail calls to this function. */ + if (trustedCertList) { ++ /* CERT_DestroyCertList destroys interior certs for us. */ + CERT_DestroyCertList(trustedCertList); + trustedCertList = NULL; + } + +- /* CERT_DestroyCertList destroys interior certs for us. */ +- +- if(root) { +- root = NULL; +- } +- +- if(res == SECSuccess && usage) { ++ if (res == SECSuccess && usage && usageIndex != -1) { + *usage = cvout[usageIndex].value.scalar.usages; + } + + return res; + } ++ ++/* Verify a cert using an explicit PKIX call. For now only perform this call ++ * when the OCSP policy is set to leaf and chain. Performs a blocking, online ++ * OCSP status refresh. The result of this call will be a full-chain OCSP ++ * validation. ++ * ++ * In the future, we'll use ocspPolicy to condition around additional policies ++ * and handle them all with this method (and a call to PKIX). ++ * ++ * Note that this currently requires the certificate to be added directly ++ * to the NSS DB. We can't otherwise validate against root certificates in ++ * the default NSS DB. ++ */ ++SECStatus JSSL_verifyCertPKIX(CERTCertificate *cert, ++ SECCertificateUsage certificateUsage, secuPWData *pwdata, int ocspPolicy, ++ CERTVerifyLog *log, SECCertificateUsage *usage) ++{ ++ SECCertUsage certUsage = certUsageSSLClient /* 0 */; ++ ++ /* We need to convert the SECCertificateUsage to a SECCertUsage to obtain ++ * the root. ++ */ ++ ++ SECCertificateUsage testUsage = certificateUsage; ++ while (0 != (testUsage = testUsage >> 1)) { certUsage++; } ++ ++ CERTCertificate *root = getRoot(cert, certUsage); ++ ++ // Two cases: either the root is present, or it isn't. ++ if (root == NULL) { ++ /* In this case, we've had a hard time finding the root. In all ++ * likelihood, the following call will fail to validate the end cert ++ * as well and thus fail to validate. I don't believe there's a risk ++ * in trying it however. */ ++ return JSSL_verifyCertPKIXInternal(cert, certificateUsage, pwdata, ++ ocspPolicy, log, usage, NULL); ++ } else { ++ /* In this case, we've found the root certificate. Before passing it ++ * to the leaf, explicitly validate it with strict OCSP checking. Then ++ * validate the leaf certificate with a known and trusted root ++ * certificate. */ ++ SECStatus ret = JSSL_verifyCertPKIXInternal(root, certificateUsageSSLCA, ++ pwdata, ocspPolicy, log, usage, NULL); ++ if (ret != SECSuccess) { ++ return ret; ++ } ++ ++ CERTCertList *rootList = CERT_NewCertList(); ++ CERT_AddCertToListTail(rootList, root); ++ return JSSL_verifyCertPKIXInternal(cert, certificateUsage, pwdata, ++ ocspPolicy, log, usage, rootList); ++ } ++} +-- +2.21.0 + diff --git a/SOURCES/0002-Add-script-to-add-common-root-CAs.patch b/SOURCES/0002-Add-script-to-add-common-root-CAs.patch new file mode 100644 index 0000000..cde61fe --- /dev/null +++ b/SOURCES/0002-Add-script-to-add-common-root-CAs.patch @@ -0,0 +1,59 @@ +From 61985f642b0b5cc75fc3f254ef6c99aeb56acbe2 Mon Sep 17 00:00:00 2001 +From: Alexander Scheel +Date: Thu, 29 Aug 2019 16:14:08 -0400 +Subject: [PATCH 2/3] Add script to add common root CAs + +When given an NSS DB, common_roots.sh uses the trust command to extract +the root CAs trusted by the local system and add them to said NSS DB. + +Signed-off-by: Alexander Scheel +--- + tools/common_roots.sh | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + create mode 100755 tools/common_roots.sh + +diff --git a/tools/common_roots.sh b/tools/common_roots.sh +new file mode 100755 +index 00000000..97341c4c +--- /dev/null ++++ b/tools/common_roots.sh +@@ -0,0 +1,36 @@ ++#!/bin/bash ++ ++# This script reads the contents of the OS CA bundle store, ++# /usr/share/pki/ca-trust-source/ca-bundle.trust.p11-kit ++# and places the contained CAs into the specified NSS DB. ++# ++# This NSS DB is used by various JSS tests that aren't enabled ++# by default because they require an active internet connection. ++ ++nssdb="$1" ++ ++if [ -z "$nssdb" ] && [ -e "build" ]; then ++ nssdb="build/results/cadb" ++elif [ -z "$nssdb" ] && [ -e "../build" ]; then ++ nssdb="../build/results/cadb" ++else ++ echo "Must provide path to NSS DB!" 1>&2 ++ exit 1 ++fi ++ ++if [ -e "$nssdb" ]; then ++ rm -rf "$nssdb" ++fi ++ ++mkdir -p "$nssdb" ++echo "" > "$nssdb/password.txt" ++certutil -N -d "$nssdb" -f "$nssdb/password.txt" ++ ++trust extract --format=pem-bundle --filter=ca-anchors "$nssdb/complete.pem" ++ ++# From: https://serverfault.com/questions/391396/how-to-split-a-pem-file ++csplit -f "$nssdb/individual-" "$nssdb/complete.pem" '/-----BEGIN CERTIFICATE-----/' '{*}' ++ ++for cert in "$nssdb"/individual*; do ++ certutil -A -a -i "$cert" -n "$cert" -t CT,C,C -d "$nssdb" -f "$nssdb/password.txt" ++done +-- +2.21.0 + diff --git a/SOURCES/0003-Add-optional-test-case-against-badssl.com.patch b/SOURCES/0003-Add-optional-test-case-against-badssl.com.patch new file mode 100644 index 0000000..ba155f1 --- /dev/null +++ b/SOURCES/0003-Add-optional-test-case-against-badssl.com.patch @@ -0,0 +1,233 @@ +From 7b4c0fa04f5e4469fc8bc442c9f12f975c5e1610 Mon Sep 17 00:00:00 2001 +From: Alexander Scheel +Date: Wed, 28 Aug 2019 09:23:41 -0400 +Subject: [PATCH 3/3] Add optional test case against badssl.com + +badssl.com maintains a number of subdomains with valid and invalid TLS +configurations. A number of these test certificates which fail in +certain scenarios (revoked, expired, etc). Add a test runner which +validates SSLSocket's implementation against badssl.com. + +Signed-off-by: Alexander Scheel +--- + org/mozilla/jss/tests/BadSSL.java | 208 ++++++++++++++++++++++++++++++ + 1 file changed, 208 insertions(+) + create mode 100644 org/mozilla/jss/tests/BadSSL.java + +diff --git a/org/mozilla/jss/tests/BadSSL.java b/org/mozilla/jss/tests/BadSSL.java +new file mode 100644 +index 00000000..60bfe820 +--- /dev/null ++++ b/org/mozilla/jss/tests/BadSSL.java +@@ -0,0 +1,208 @@ ++package org.mozilla.jss.tests; ++ ++import org.mozilla.jss.CryptoManager; ++ ++import org.mozilla.jss.ssl.SSLSocket; ++import org.mozilla.jss.ssl.SSLSocketException; ++ ++import org.mozilla.jss.util.NativeErrcodes; ++ ++/** ++ * The BadSSL test case maintains an internal mapping from badssl.com ++ * subdomains to expected exceptions and validates they occur. ++ * ++ * Since badssl.com offers no guaranteed SLA or availability, we likely ++ * shouldn't add this site to automated tests. ++ */ ++ ++public class BadSSL { ++ public static void main(String[] args) throws Exception { ++ boolean ocsp = false; ++ ++ if (args.length < 1) { ++ System.out.println("Usage: BadSSL nssdb [LEAF_AND_CHAIN]"); ++ return; ++ } ++ ++ if (args.length >= 2 && args[1].equals("LEAF_AND_CHAIN")) { ++ System.out.println("Enabling leaf and chain policy..."); ++ ocsp = true; ++ } ++ ++ CryptoManager.initialize(args[0]); ++ CryptoManager cm = CryptoManager.getInstance(); ++ ++ if (ocsp) { ++ cm.setOCSPPolicy(CryptoManager.OCSPPolicy.LEAF_AND_CHAIN); ++ } ++ ++ ++ // Test cases which should fail due to various certificate errors. ++ testExpired(); ++ testWrongHost(); ++ testSelfSigned(); ++ testUntrustedRoot(); ++ ++ // The following test cases depend on crypto-policies or local NSS ++ // configuration. ++ testSHA1(); ++ testRC4MD5(); ++ testRC4(); ++ test3DES(); ++ testNULL(); ++ ++ // The following test cases depend on OCSP being enabled. ++ if (ocsp) { ++ testRevoked(); ++ } ++ ++ // Test cases which should pass given the correct root certs. ++ testSHA256(); ++ testSHA384(); ++ testSHA512(); ++ ++ testECC256(); ++ testECC384(); ++ ++ testRSA2048(); ++ testRSA4096(); ++ testRSA8192(); ++ ++ testExtendedValidation(); ++ } ++ ++ /* Test cases whose handshakes should fail below. */ ++ ++ public static void testExpired() throws Exception { ++ testHelper("expired.badssl.com", 443, new String[]{ "(-8181)", "has expired" }); ++ } ++ ++ public static void testWrongHost() throws Exception { ++ testHelper("wrong.host.badssl.com", 443, new String[]{ "(-12276)", "domain name does not match" }); ++ } ++ ++ public static void testSelfSigned() throws Exception { ++ testHelper("self-signed.badssl.com", 443, new String[]{ "(-8101)", "(-8156)", "type not approved", "issuer certificate is invalid" }); ++ } ++ ++ public static void testUntrustedRoot() throws Exception { ++ testHelper("untrusted-root.badssl.com", 443, new String[]{ "(-8172)", "certificate issuer has been marked as not trusted" }); ++ } ++ ++ public static void testRevoked() throws Exception { ++ testHelper("revoked.badssl.com", 443, new String[]{ "(-8180)", "has been revoked" }); ++ } ++ ++ public static void testSHA1() throws Exception { ++ testHelper("sha1-intermediate.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); ++ } ++ ++ public static void testRC4MD5() throws Exception { ++ testHelper("rc4-md5.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); ++ } ++ ++ public static void testRC4() throws Exception { ++ testHelper("rc4.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); ++ } ++ ++ public static void test3DES() throws Exception { ++ testHelper("3des.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); ++ } ++ ++ public static void testNULL() throws Exception { ++ testHelper("null.badssl.com", 443, new String[] { "(-12286)", "Cannot communicate securely" }); ++ } ++ ++ /* Test cases which should handshake successfully below. */ ++ ++ public static void testSHA256() throws Exception { ++ testHelper("sha256.badssl.com", 443); ++ } ++ ++ public static void testSHA384() throws Exception { ++ testHelper("sha384.badssl.com", 443); ++ } ++ ++ public static void testSHA512() throws Exception { ++ testHelper("sha512.badssl.com", 443); ++ } ++ ++ public static void testECC256() throws Exception { ++ testHelper("ecc256.badssl.com", 443); ++ } ++ ++ public static void testECC384() throws Exception { ++ testHelper("ecc384.badssl.com", 443); ++ } ++ ++ public static void testRSA2048() throws Exception { ++ testHelper("rsa2048.badssl.com", 443); ++ } ++ ++ public static void testRSA4096() throws Exception { ++ testHelper("rsa4096.badssl.com", 443); ++ } ++ ++ public static void testRSA8192() throws Exception { ++ testHelper("rsa8192.badssl.com", 443); ++ } ++ ++ public static void testExtendedValidation() throws Exception { ++ testHelper("extended-validation.badssl.com", 443); ++ } ++ ++ /* Test case helpers. */ ++ ++ public static void testHelper(String host, int port) throws Exception { ++ testSite(host, port); ++ System.out.println("\t...ok"); ++ } ++ ++ public static void testHelper(String host, int port, String[] substrs) throws Exception { ++ try { ++ testSite(host, port); ++ } catch (SSLSocketException sse) { ++ String actual = sse.getMessage().toLowerCase(); ++ ++ for (String expected : substrs) { ++ if (actual.contains(expected.toLowerCase())) { ++ System.out.println("\t...got expected error message."); ++ return; ++ } ++ } ++ ++ System.err.println("\tUnexpected error message: " + actual); ++ throw sse; ++ } ++ ++ throw new RuntimeException("Expected to get an exception, but didn't!"); ++ } ++ ++ public static void testHelper(String host, int port, int[] codes) throws Exception { ++ try { ++ testSite(host, port); ++ } catch (SSLSocketException sse) { ++ int actual = sse.getErrcode(); ++ for (int expected : codes) { ++ if (actual == expected) { ++ System.out.println("\t...got expected error code."); ++ return; ++ } ++ } ++ ++ System.err.println("\tUnexpected error code: " + actual); ++ throw sse; ++ } ++ ++ throw new RuntimeException("Expected to get an exception, but didn't!"); ++ } ++ ++ public static void testSite(String host, int port) throws Exception { ++ System.out.println("Testing connection to " + host + ":" + port); ++ SSLSocket sock = new SSLSocket(host, 443); ++ sock.forceHandshake(); ++ sock.shutdownOutput(); ++ sock.shutdownInput(); ++ sock.close(); ++ } ++} +-- +2.21.0 + diff --git a/SPECS/jss.spec b/SPECS/jss.spec new file mode 100644 index 0000000..59edb0f --- /dev/null +++ b/SPECS/jss.spec @@ -0,0 +1,206 @@ +################################################################################ +Name: jss +################################################################################ + +Summary: Java Security Services (JSS) +URL: http://www.dogtagpki.org/wiki/JSS +License: MPLv1.1 or GPLv2+ or LGPLv2+ + +Version: 4.4.7 +Release: 2%{?dist} + +# To generate the source tarball: +# $ git clone https://github.com/dogtagpki/jss.git +# $ cd jss +# $ git tag v4.4. +# $ git push origin v4.4. +# Then go to https://github.com/dogtagpki/jss/releases and download the source +# tarball. +Source: https://github.com/dogtagpki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz + +# To create a patch for all changes since a version tag: +# $ git format-patch \ +# --stdout \ +# \ +# > jss-VERSION-RELEASE.patch +Patch1: 0001-JSS-CVE-2019-14823-fix.patch +Patch2: 0002-Add-script-to-add-common-root-CAs.patch +Patch3: 0003-Add-optional-test-case-against-badssl.com.patch + +Conflicts: idm-console-framework < 1.1.17-4 +Conflicts: pki-base < 10.4.0 +Conflicts: tomcatjss < 7.2.1 + +# autosetup +BuildRequires: git + +BuildRequires: nss-devel >= 3.28.4-6 +BuildRequires: nspr-devel >= 4.13.1 +BuildRequires: java-1.8.0-openjdk-devel +BuildRequires: jpackage-utils +%if 0%{?fedora} >= 25 || 0%{?rhel} > 7 +BuildRequires: perl-interpreter +%endif +BuildRequires: apache-commons-lang +BuildRequires: apache-commons-codec + +Requires: nss >= 3.28.4-6 +Requires: java-1.8.0-openjdk-headless +Requires: jpackage-utils +Requires: apache-commons-lang +Requires: apache-commons-codec + +%description +Java Security Services (JSS) is a java native interface which provides a bridge +for java-based applications to use native Network Security Services (NSS). +This only works with gcj. Other JREs require that JCE providers be signed. + +################################################################################ +%package javadoc +################################################################################ + +Summary: Java Security Services (JSS) Javadocs +Group: Documentation +Requires: jss = %{version}-%{release} + +%description javadoc +This package contains the API documentation for JSS. + +################################################################################ +%prep + +%autosetup -n %{name}-%{version} -p 1 -S git + +# Prior to version 4.4.5, the source code were stored under "jss-/jss" +# path in the source tarball. Starting from version 4.4.5, the files will be +# stored under "jss-" path. However, since the build system is still +# using the old path (introduced via sandboxing), the unpacked source code has +# to be moved to the old path with the following commands. Otherwise, even +# though we're linking against system libraries, the build will complain about +# a missing sandbox. + +cd .. +mv %{name}-%{version} jss +mkdir %{name}-%{version} +mv jss %{name}-%{version} + +################################################################################ +%build + +%if 0%{?fedora} >= 27 +%set_build_flags +%endif + +[ -z "$JAVA_HOME" ] && export JAVA_HOME=%{_jvmdir}/java +[ -z "$USE_INSTALLED_NSPR" ] && export USE_INSTALLED_NSPR=1 +[ -z "$USE_INSTALLED_NSS" ] && export USE_INSTALLED_NSS=1 + +# Enable compiler optimizations and disable debugging code +# NOTE: If you ever need to create a debug build with optimizations disabled +# just comment out this line and change in the %%install section below the +# line that copies jars xpclass.jar to be xpclass_dbg.jar +export BUILD_OPT=1 + +# Generate symbolic info for debuggers +XCFLAGS="-g $RPM_OPT_FLAGS" +export XCFLAGS + +PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 +PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 + +export PKG_CONFIG_ALLOW_SYSTEM_LIBS +export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS + +NSPR_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nspr | sed 's/-I//'` +NSPR_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nspr | sed 's/-L//'` + +NSS_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nss | sed 's/-I//'` +NSS_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nss | sed 's/-L//'` + +export NSPR_INCLUDE_DIR +export NSPR_LIB_DIR +export NSS_INCLUDE_DIR +export NSS_LIB_DIR + +%if 0%{?__isa_bits} == 64 +USE_64=1 +export USE_64 +%endif + +# The Makefile is not thread-safe +make -C jss/coreconf +make -C jss +make -C jss javadoc + +################################################################################ +%install + +# Copy the license files here so we can include them in %%doc +cp -p jss/MPL-1.1.txt . +cp -p jss/gpl.txt . +cp -p jss/lgpl.txt . + +# There is no install target so we'll do it by hand + +# jars +install -d -m 0755 $RPM_BUILD_ROOT%{_jnidir} +# NOTE: if doing a debug no opt build change xpclass.jar to xpclass_dbg.jar +install -m 644 dist/xpclass.jar ${RPM_BUILD_ROOT}%{_jnidir}/jss4.jar + +# We have to use the name libjss4.so because this is dynamically +# loaded by the jar file. +install -d -m 0755 $RPM_BUILD_ROOT%{_libdir}/jss +install -m 0755 dist/Linux*.OBJ/lib/libjss4.so ${RPM_BUILD_ROOT}%{_libdir}/jss/ +pushd ${RPM_BUILD_ROOT}%{_libdir}/jss + ln -fs %{_jnidir}/jss4.jar jss4.jar +popd + +# javadoc +install -d -m 0755 $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} +cp -rp dist/jssdoc/* $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} +cp -p jss/jss.html $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} +cp -p jss/*.txt $RPM_BUILD_ROOT%{_javadocdir}/%{name}-%{version} + +# No ldconfig is required since this library is loaded by Java itself. +################################################################################ +%files + +%defattr(-,root,root,-) +%doc jss/jss.html jss/MPL-1.1.txt jss/gpl.txt jss/lgpl.txt +%{_libdir}/jss/* +%{_jnidir}/* +%{_libdir}/jss/lib*.so + +################################################################################ +%files javadoc + +%defattr(-,root,root,-) +%dir %{_javadocdir}/%{name}-%{version} +%{_javadocdir}/%{name}-%{version}/* + +################################################################################ +%changelog +* Wed Sep 11 2019 Dogtag PKI Team 4.4.7-2 +- Bugzilla #1747967 - CVE 2019-14823 jss: OCSP policy "Leaf and Chain" implicitly trusts the root certificate + +* Mon Aug 5 2019 Dogtag PKI Team 4.4.7-1 +- Bugzilla #1733590 - Rebase JSS in RHEL 7.8 (ascheel) + +* Fri Mar 15 2019 Dogtag PKI Team 4.4.6-1 +- Bugzilla #1659527 - Rebase JSS in RHEL 7.7 (ascheel) + +* Thu Jul 5 2018 Dogtag PKI Team 4.4.4-3 +- Bugzilla #1534772 - org.mozilla.jss.pkix.primitive.AlgorithmIdentifier + decode/encode process alters original data (cfu) +- Bugzilla #1554056 - JSS: Add support for TLS_*_SHA384 ciphers (cfu) + +* Thu Jun 21 2018 Dogtag PKI Team 4.4.4-2 +- Red Hat Bugzilla #1560682 - (RFE) Migrate RHCS x509 cert and crl + functionality to JSS (jmagne) + +* Tue May 29 2018 Dogtag PKI Team 4.4.4-1 +- Rebased to JSS 4.4.4 + +* Thu Apr 05 2018 Dogtag PKI Team 4.4.3-1 +- Rebased to JSS 4.4.3 +#- Red Hat Bugzilla #1548548 - Partial Fedora build flags injection