diff --git a/SOURCES/python-nss-doc-manifest.patch b/SOURCES/python-nss-doc-manifest.patch new file mode 100644 index 0000000..4ddee79 --- /dev/null +++ b/SOURCES/python-nss-doc-manifest.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User John Dennis +# Date 1420558515 18000 +# Tue Jan 06 10:35:15 2015 -0500 +# Node ID 22895012dc87281141bf15494bb860e68b37ecc6 +# Parent 46403a1eb97050a09eb8c4e6adf428c742ab9c5f +fix install_doc manifest, it omitted the run_tests script. + +Tighten up the manifest regular expressions. +Exclude the pki directory from doc/examples and test. + +diff --git a/setup.py b/setup.py +--- a/setup.py ++++ b/setup.py +@@ -21,9 +21,11 @@ + + doc_manifest = [ + [['include README LICENSE* doc/ChangeLog', +- 'recursive-include doc *.py *.txt',], ++ 'recursive-include doc *.py *.txt', ++ 'prune doc/examples/pki'], + [('^doc/', '')], None], +- [['recursive-include test *.py *.txt',], ++ [['recursive-include test run_tests setup_certs.py test_*.py util.py *.txt', ++ 'prune test/pki'], + None , None], + [['recursive-include lib *.py *.txt',], + [('^lib/', '')] , 'examples'], diff --git a/SOURCES/python-nss-file-like-read.patch b/SOURCES/python-nss-file-like-read.patch new file mode 100644 index 0000000..b7d64cb --- /dev/null +++ b/SOURCES/python-nss-file-like-read.patch @@ -0,0 +1,49 @@ +fix read_data_from_file(), make it accept any file like object + +read_data_from_file() was supposed to accept either a string +representing a filename to open or a file object on which it will +call read() to load the contents. However the test for a file object +was too restrictive, it literally checked for a file object which +excluded objects supporting the file interface +(e.g. StringIO). Therefore the test was changed to test if the object +has a read() method. + +diff -r -u python-nss-0.16.0.orig/src/py_nss.c python-nss-0.16.0/src/py_nss.c +--- python-nss-0.16.0.orig/src/py_nss.c 2014-10-23 19:15:12.000000000 -0400 ++++ python-nss-0.16.0/src/py_nss.c 2015-05-26 17:16:50.373886276 -0400 +@@ -1796,6 +1796,20 @@ + return py_sec_item; + } + ++static bool ++pyobject_has_method(PyObject* obj, const char *method_name) ++{ ++ PyObject *attr; ++ int is_callable; ++ ++ if ((attr = PyObject_GetAttrString(obj, method_name)) == NULL) { ++ return false; ++ } ++ is_callable = PyCallable_Check(attr); ++ Py_DECREF(attr); ++ return is_callable ? true : false; ++} ++ + /* + * read_data_from_file(PyObject *file_arg) + * +@@ -1819,11 +1833,11 @@ + if ((py_file = PyFile_FromString(PyString_AsString(file_arg), "r")) == NULL) { + return NULL; + } +- } else if (PyFile_Check(file_arg)) { ++ } else if (pyobject_has_method(file_arg, "read")) { + py_file = file_arg; + Py_INCREF(py_file); + } else { +- PyErr_SetString(PyExc_TypeError, "Bad file, must be pathname or file object"); ++ PyErr_SetString(PyExc_TypeError, "Bad file, must be pathname or file like object with read() method"); + return NULL; + } + +Only in python-nss-0.16.0/src: py_nss.c~ diff --git a/SOURCES/python-nss-set_certificate_db.patch b/SOURCES/python-nss-set_certificate_db.patch new file mode 100644 index 0000000..c597e83 --- /dev/null +++ b/SOURCES/python-nss-set_certificate_db.patch @@ -0,0 +1,26 @@ +# HG changeset patch +# User John Dennis +# Date 1434146562 14400 +# Fri Jun 12 18:02:42 2015 -0400 +# Node ID 932c56dbe8dbf74ca90461770f40c4ae2c79fe62 +# Parent 6096d0660e2abefcee12e502fed029663d435c54 +SSLSocket.set_certificate_db() fails with TypeError + +Resolves bug +https://bugzilla.redhat.com/show_bug.cgi?id=1230584 + +The PyArg_ParseTuple parameters were incorrectly specified, +it passed a type instead of a pointer to type. + +diff --git a/src/py_ssl.c b/src/py_ssl.c +--- a/src/py_ssl.c ++++ b/src/py_ssl.c +@@ -1638,7 +1638,7 @@ + { + CertDB *py_certdb = NULL; + +- if (!PyArg_ParseTuple(args, "O!:set_certificate_db", CertDBType, &py_certdb)) ++ if (!PyArg_ParseTuple(args, "O!:set_certificate_db", &CertDBType, &py_certdb)) + return NULL; + + if (SSL_CertDBHandleSet(self->pr_socket, py_certdb->handle) != SECSuccess) { diff --git a/SOURCES/python-nss-test-fips.patch b/SOURCES/python-nss-test-fips.patch new file mode 100644 index 0000000..b280e53 --- /dev/null +++ b/SOURCES/python-nss-test-fips.patch @@ -0,0 +1,228 @@ +# HG changeset patch +# User John Dennis +# Date 1434146324 14400 +# Fri Jun 12 17:58:44 2015 -0400 +# Node ID 6096d0660e2abefcee12e502fed029663d435c54 +# Parent a5e07e90e9c8cb08c5fb46eba16bdb43b94d67c3 +Some unit tests fail in FIPS mode + +Resolves bug +https://bugzilla.redhat.com/show_bug.cgi?id=1194349 + +Essentially there were 2 problems: + +1. The DB password 'db_passwd' was not complex enough for FIPS + changing it to 'DB_passwd' with upper case was sufficient. + Also changed the pkcs password 'pk12_passwd' to 'PK12_passwd' + +2. NSS adds a random salt in FIPS mode for the PKCS12 operations. + The presence of this salt was causing a comparision to fail, + the exact salt is insignificant to the operation of the test + so it was stripped out prior to comparision. + +At the same time setup_certs.py was augmented to accept a --fips +parameter to put the DB into fips mode and setup_certs.py also +now reports the status of the system FIPS mode and DB FIPS mode in +addtion to the existing info displayed at its conclusion. + +diff --git a/test/setup_certs.py b/test/setup_certs.py +--- a/test/setup_certs.py ++++ b/test/setup_certs.py +@@ -4,6 +4,7 @@ + import atexit + import logging + import os ++import re + import shutil + import subprocess + import sys +@@ -11,6 +12,12 @@ + import tempfile + + #------------------------------------------------------------------------------- ++logger = None ++ ++FIPS_SWITCH_FAILED_ERR = 11 ++FIPS_ALREADY_ON_ERR = 12 ++FIPS_ALREADY_OFF_ERR = 13 ++ + + class CmdError(Exception): + def __init__(self, cmd_args, returncode, message=None, stdout=None, stderr=None): +@@ -41,7 +48,7 @@ + returncode = p.returncode + if returncode != 0: + raise CmdError(cmd_args, returncode, +- 'failed %s' % (', '.join(cmd_args)), ++ 'failed %s' % (' '.join(cmd_args)), + stdout, stderr) + return stdout, stderr + except OSError as e: +@@ -319,9 +326,75 @@ + run_cmd(cmd_args) + return name + ++def parse_fips_enabled(string): ++ if re.search('FIPS mode disabled', string): ++ return False ++ if re.search('FIPS mode enabled', string): ++ return True ++ raise ValueError('unknown fips enabled string: "%s"' % string) ++ ++def get_system_fips_enabled(): ++ fips_path = '/proc/sys/crypto/fips_enabled' ++ ++ try: ++ with open(fips_path) as f: ++ data = f.read() ++ except Exception as e: ++ logger.warning("Unable to determine system FIPS mode: %s" % e) ++ data = '0' ++ ++ value = int(data) ++ if value: ++ return True ++ else: ++ return False ++ ++ ++def get_db_fips_enabled(db_name): ++ cmd_args = ['/usr/bin/modutil', ++ '-dbdir', db_name, # NSS database ++ '-chkfips', 'true', # enable/disable fips ++ ] ++ ++ try: ++ stdout, stderr = run_cmd(cmd_args) ++ return parse_fips_enabled(stdout) ++ except CmdError as e: ++ if e.returncode == FIPS_SWITCH_FAILED_ERR: ++ return parse_fips_enabled(e.stdout) ++ else: ++ raise ++ ++def set_fips_mode(options): ++ if options.fips: ++ state = 'true' ++ else: ++ if get_system_fips_enabled(): ++ logger.warning("System FIPS enabled, cannot disable FIPS") ++ return ++ state = 'false' ++ ++ logging.info('setting fips: %s', state) ++ ++ cmd_args = ['/usr/bin/modutil', ++ '-dbdir', options.db_name, # NSS database ++ '-fips', state, # enable/disable fips ++ '-force' ++ ] ++ ++ try: ++ stdout, stderr = run_cmd(cmd_args) ++ except CmdError as e: ++ if options.fips and e.returncode == FIPS_ALREADY_ON_ERR: ++ pass ++ elif not options.fips and e.returncode == FIPS_ALREADY_OFF_ERR: ++ pass ++ else: ++ raise + #------------------------------------------------------------------------------- + + def setup_certs(args): ++ global logger + + # --- cmd --- + parser = argparse.ArgumentParser(description='create certs for testing', +@@ -393,6 +466,9 @@ + parser.add_argument('--serial-file', dest='serial_file', + help='name of file used to track next serial number') + ++ parser.add_argument('--db-fips', action='store_true', ++ help='enable FIPS mode on NSS Database') ++ + parser.set_defaults(verbose = False, + debug = False, + quiet = False, +@@ -402,7 +478,7 @@ + hostname = os.uname()[1], + db_type = 'sql', + db_dir = 'pki', +- db_passwd = 'db_passwd', ++ db_passwd = 'DB_passwd', + ca_subject = 'CN=Test CA', + ca_nickname = 'test_ca', + server_subject = 'CN=${hostname}', +@@ -416,6 +492,7 @@ + valid_months = 12, + ca_path_len = 2, + serial_file = '${db_dir}/serial', ++ fips = False, + ) + + +@@ -468,6 +545,7 @@ + + try: + create_database(options) ++ set_fips_mode(options) + cert_nicknames.append(create_ca_cert(options)) + cert_nicknames.append(create_server_cert(options)) + cert_nicknames.append(create_client_cert(options)) +@@ -488,6 +566,8 @@ + logging.info('---------- Summary ----------') + logging.info('NSS database name="%s", password="%s"', + options.db_name, options.db_passwd) ++ logging.info('system FIPS mode=%s', get_system_fips_enabled()); ++ logging.info('DB FIPS mode=%s', get_db_fips_enabled(options.db_name)); + logging.info('CA nickname="%s", CA subject="%s"', + options.ca_nickname, options.ca_subject) + logging.info('server nickname="%s", server subject="%s"', +diff --git a/test/test_client_server.py b/test/test_client_server.py +--- a/test/test_client_server.py ++++ b/test/test_client_server.py +@@ -22,7 +22,7 @@ + + verbose = False + info = False +-password = 'db_passwd' ++password = 'DB_passwd' + use_ssl = True + client_cert_action = NO_CLIENT_CERT + db_name = 'sql:pki' +diff --git a/test/test_pkcs12.py b/test/test_pkcs12.py +--- a/test/test_pkcs12.py ++++ b/test/test_pkcs12.py +@@ -15,8 +15,8 @@ + + verbose = False + db_name = 'sql:pki' +-db_passwd = 'db_passwd' +-pk12_passwd = 'pk12_passwd' ++db_passwd = 'DB_passwd' ++pk12_passwd = 'PK12_passwd' + + cert_nickname = 'test_user' + pk12_filename = '%s.p12' % cert_nickname +@@ -115,6 +115,9 @@ + raise ValueError('Could not file Key section in pk12 listing') + return text[match.start(0):] + ++def strip_salt_from_pk12_listing(text): ++ return re.sub(r'\s+Salt:\s*\n.*', '', text) ++ + #------------------------------------------------------------------------------- + + def load_tests(loader, tests, pattern): +@@ -206,9 +209,11 @@ + + pk12_listing = list_pk12(pk12_filename) + pk12_listing = strip_key_from_pk12_listing(pk12_listing) ++ pk12_listing = strip_salt_from_pk12_listing(pk12_listing) + + exported_pk12_listing = list_pk12(exported_pk12_filename) + exported_pk12_listing = strip_key_from_pk12_listing(exported_pk12_listing) ++ exported_pk12_listing = strip_salt_from_pk12_listing(exported_pk12_listing) + + self.assertEqual(pk12_listing, exported_pk12_listing) + diff --git a/SPECS/python-nss.spec b/SPECS/python-nss.spec index f50ec95..1cd632b 100644 --- a/SPECS/python-nss.spec +++ b/SPECS/python-nss.spec @@ -6,7 +6,7 @@ Name: python-nss Version: 0.16.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Python bindings for Network Security Services (NSS) Group: Development/Languages @@ -16,6 +16,10 @@ Source0: ftp://ftp.mozilla.org/pub/mozilla.org/security/python-nss/releas BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Patch1: nss-version.patch +Patch2: python-nss-file-like-read.patch +Patch3: python-nss-test-fips.patch +Patch4: python-nss-set_certificate_db.patch +Patch5: python-nss-doc-manifest.patch %global docdir %{_docdir}/%{name}-%{version} @@ -26,7 +30,7 @@ Patch1: nss-version.patch } BuildRequires: python-devel -BuildRequires: python-setuptools-devel +BuildRequires: python-setuptools BuildRequires: python-docutils BuildRequires: nspr-devel BuildRequires: nss-devel @@ -53,6 +57,10 @@ API documentation and examples %prep %setup -q %patch1 -p1 -b .nss-version +%patch2 -p1 -b .file-like +%patch3 -p1 -b .fips-test +%patch4 -p1 -b .set_certificate_db +%patch5 -p1 -b .doc-manifest %build CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" %{__python} setup.py build @@ -94,6 +102,14 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Tue May 26 2015 John Dennis - 0.16.0-3 +- Resolves: #1225212 + Reads from file like objects actually only worked for file objects +- Resolves: #1179573 + python-nss-doc package is missing the run_tests script +- Resolves: #1194349 + test_pkcs12.py does not works in FIPS mode + * Tue Nov 25 2014 John Dennis - 0.16.0-2 - Remove the TLS 1.3 symbols from ssl_version_range.py example because RHEL only has NSS 3.16.