2018-04-05 02:21:16 -05:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2017-11-08 05:10:54 -06:00
|
|
|
import os
|
|
|
|
|
2018-02-08 06:40:34 -06:00
|
|
|
import pytest
|
|
|
|
|
2020-08-27 04:07:40 -05:00
|
|
|
from ipapython.certdb import (
|
|
|
|
NSSDatabase,
|
|
|
|
TRUSTED_PEER_TRUST_FLAGS,
|
|
|
|
nss_supports_dbm,
|
|
|
|
)
|
2019-07-08 04:25:13 -05:00
|
|
|
from ipapython import ipautil
|
2018-08-29 05:43:03 -05:00
|
|
|
from ipaplatform.osinfo import osinfo
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
CERTNICK = 'testcert'
|
2019-12-10 05:46:14 -06:00
|
|
|
CERTSAN = 'testcert.certdb.test'
|
2017-11-08 05:10:54 -06:00
|
|
|
|
2018-08-29 05:43:03 -05:00
|
|
|
if osinfo.id == 'fedora':
|
2019-02-28 08:47:19 -06:00
|
|
|
if osinfo.version_number >= (28,):
|
2018-02-08 06:40:34 -06:00
|
|
|
NSS_DEFAULT = 'sql'
|
|
|
|
else:
|
|
|
|
NSS_DEFAULT = 'dbm'
|
|
|
|
else:
|
|
|
|
NSS_DEFAULT = None
|
|
|
|
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
def create_selfsigned(nssdb):
|
|
|
|
# create self-signed cert + key
|
|
|
|
noisefile = os.path.join(nssdb.secdir, 'noise')
|
|
|
|
with open(noisefile, 'wb') as f:
|
|
|
|
f.write(os.urandom(64))
|
|
|
|
try:
|
|
|
|
nssdb.run_certutil([
|
|
|
|
'-S', '-x',
|
|
|
|
'-z', noisefile,
|
|
|
|
'-k', 'rsa', '-g', '2048', '-Z', 'SHA256',
|
|
|
|
'-t', 'CTu,Cu,Cu',
|
|
|
|
'-s', 'CN=testcert',
|
|
|
|
'-n', CERTNICK,
|
|
|
|
'-m', '365',
|
2019-12-10 05:46:14 -06:00
|
|
|
'--extSAN', f'dns:{CERTSAN}'
|
2017-11-08 05:10:54 -06:00
|
|
|
])
|
|
|
|
finally:
|
|
|
|
os.unlink(noisefile)
|
|
|
|
|
|
|
|
|
2020-08-27 04:07:40 -05:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
not nss_supports_dbm(),
|
|
|
|
reason="NSS is built without support of the legacy database(DBM)",
|
|
|
|
)
|
2017-11-08 05:10:54 -06:00
|
|
|
def test_dbm_tmp():
|
|
|
|
with NSSDatabase(dbtype='dbm') as nssdb:
|
|
|
|
assert nssdb.dbtype == 'dbm'
|
|
|
|
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert not os.path.isfile(filename)
|
2018-01-16 07:57:07 -06:00
|
|
|
assert not nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
nssdb.create_db()
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert os.path.isfile(filename)
|
|
|
|
assert os.path.dirname(filename) == nssdb.secdir
|
2018-01-16 07:57:07 -06:00
|
|
|
assert nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
assert os.path.basename(nssdb.certdb) == 'cert8.db'
|
|
|
|
assert nssdb.certdb in nssdb.filenames
|
|
|
|
assert os.path.basename(nssdb.keydb) == 'key3.db'
|
|
|
|
assert os.path.basename(nssdb.secmod) == 'secmod.db'
|
|
|
|
|
|
|
|
|
2020-08-27 04:07:40 -05:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
nss_supports_dbm(),
|
|
|
|
reason="NSS is built with support of the legacy database(DBM)",
|
|
|
|
)
|
|
|
|
def test_dbm_raise():
|
|
|
|
with pytest.raises(ValueError) as e:
|
|
|
|
NSSDatabase(dbtype="dbm")
|
|
|
|
assert (
|
|
|
|
str(e.value) == "NSS is built without support of the legacy "
|
|
|
|
"database(DBM)"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2017-11-08 05:10:54 -06:00
|
|
|
def test_sql_tmp():
|
|
|
|
with NSSDatabase(dbtype='sql') as nssdb:
|
|
|
|
assert nssdb.dbtype == 'sql'
|
|
|
|
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert not os.path.isfile(filename)
|
2018-01-16 07:57:07 -06:00
|
|
|
assert not nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
nssdb.create_db()
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert os.path.isfile(filename)
|
|
|
|
assert os.path.dirname(filename) == nssdb.secdir
|
2018-01-16 07:57:07 -06:00
|
|
|
assert nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
assert os.path.basename(nssdb.certdb) == 'cert9.db'
|
|
|
|
assert nssdb.certdb in nssdb.filenames
|
|
|
|
assert os.path.basename(nssdb.keydb) == 'key4.db'
|
|
|
|
assert os.path.basename(nssdb.secmod) == 'pkcs11.txt'
|
|
|
|
|
|
|
|
|
2020-08-27 04:07:40 -05:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
not nss_supports_dbm(),
|
|
|
|
reason="NSS is built without support of the legacy database(DBM)",
|
|
|
|
)
|
2017-11-08 05:10:54 -06:00
|
|
|
def test_convert_db():
|
|
|
|
with NSSDatabase(dbtype='dbm') as nssdb:
|
|
|
|
assert nssdb.dbtype == 'dbm'
|
|
|
|
|
|
|
|
nssdb.create_db()
|
2018-01-16 07:57:07 -06:00
|
|
|
assert nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
create_selfsigned(nssdb)
|
|
|
|
|
|
|
|
oldcerts = nssdb.list_certs()
|
|
|
|
assert len(oldcerts) == 1
|
|
|
|
oldkeys = nssdb.list_keys()
|
|
|
|
assert len(oldkeys) == 1
|
|
|
|
|
|
|
|
nssdb.convert_db()
|
2018-01-16 07:57:07 -06:00
|
|
|
assert nssdb.exists()
|
2017-11-08 05:10:54 -06:00
|
|
|
|
|
|
|
assert nssdb.dbtype == 'sql'
|
|
|
|
newcerts = nssdb.list_certs()
|
|
|
|
assert len(newcerts) == 1
|
|
|
|
assert newcerts == oldcerts
|
|
|
|
newkeys = nssdb.list_keys()
|
|
|
|
assert len(newkeys) == 1
|
|
|
|
assert newkeys == oldkeys
|
|
|
|
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert os.path.isfile(filename)
|
|
|
|
assert os.path.dirname(filename) == nssdb.secdir
|
|
|
|
|
|
|
|
assert os.path.basename(nssdb.certdb) == 'cert9.db'
|
|
|
|
assert nssdb.certdb in nssdb.filenames
|
|
|
|
assert os.path.basename(nssdb.keydb) == 'key4.db'
|
|
|
|
assert os.path.basename(nssdb.secmod) == 'pkcs11.txt'
|
|
|
|
|
|
|
|
|
2020-08-27 04:07:40 -05:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
not nss_supports_dbm(),
|
|
|
|
reason="NSS is built without support of the legacy database(DBM)",
|
|
|
|
)
|
2017-11-08 05:10:54 -06:00
|
|
|
def test_convert_db_nokey():
|
|
|
|
with NSSDatabase(dbtype='dbm') as nssdb:
|
|
|
|
assert nssdb.dbtype == 'dbm'
|
|
|
|
nssdb.create_db()
|
|
|
|
|
|
|
|
create_selfsigned(nssdb)
|
|
|
|
|
|
|
|
assert len(nssdb.list_certs()) == 1
|
|
|
|
assert len(nssdb.list_keys()) == 1
|
|
|
|
# remove key, readd cert
|
|
|
|
cert = nssdb.get_cert(CERTNICK)
|
|
|
|
nssdb.run_certutil(['-F', '-n', CERTNICK])
|
|
|
|
nssdb.add_cert(cert, CERTNICK, TRUSTED_PEER_TRUST_FLAGS)
|
|
|
|
assert len(nssdb.list_keys()) == 0
|
|
|
|
oldcerts = nssdb.list_certs()
|
|
|
|
assert len(oldcerts) == 1
|
|
|
|
|
|
|
|
nssdb.convert_db()
|
|
|
|
assert nssdb.dbtype == 'sql'
|
|
|
|
newcerts = nssdb.list_certs()
|
|
|
|
assert len(newcerts) == 1
|
|
|
|
assert newcerts == oldcerts
|
|
|
|
assert nssdb.get_cert(CERTNICK) == cert
|
|
|
|
newkeys = nssdb.list_keys()
|
|
|
|
assert newkeys == ()
|
|
|
|
|
|
|
|
for filename in nssdb.filenames:
|
|
|
|
assert os.path.isfile(filename)
|
|
|
|
assert os.path.dirname(filename) == nssdb.secdir
|
|
|
|
|
|
|
|
old = os.path.join(nssdb.secdir, 'cert8.db')
|
|
|
|
assert not os.path.isfile(old)
|
|
|
|
assert os.path.isfile(old + '.migrated')
|
|
|
|
|
|
|
|
assert os.path.basename(nssdb.certdb) == 'cert9.db'
|
|
|
|
assert nssdb.certdb in nssdb.filenames
|
|
|
|
assert os.path.basename(nssdb.keydb) == 'key4.db'
|
|
|
|
assert os.path.basename(nssdb.secmod) == 'pkcs11.txt'
|
2018-02-08 06:40:34 -06:00
|
|
|
|
|
|
|
|
|
|
|
def test_auto_db():
|
|
|
|
with NSSDatabase() as nssdb:
|
|
|
|
assert nssdb.dbtype == 'auto'
|
|
|
|
assert nssdb.filenames is None
|
|
|
|
assert not nssdb.exists()
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
nssdb.list_certs()
|
|
|
|
|
|
|
|
nssdb.create_db()
|
|
|
|
assert nssdb.dbtype in ('dbm', 'sql')
|
|
|
|
if NSS_DEFAULT is not None:
|
|
|
|
assert nssdb.dbtype == NSS_DEFAULT
|
|
|
|
assert nssdb.filenames is not None
|
|
|
|
assert nssdb.exists()
|
|
|
|
nssdb.list_certs()
|
2019-07-08 04:25:13 -05:00
|
|
|
|
|
|
|
|
|
|
|
def test_delete_cert_and_key():
|
|
|
|
"""Test that delete_cert + delete_key always deletes everything
|
|
|
|
|
|
|
|
Test with a NSSDB that contains:
|
|
|
|
- cert + key
|
|
|
|
- key only
|
|
|
|
- cert only
|
|
|
|
- none of them
|
|
|
|
"""
|
|
|
|
cmd = ipautil.run(['mktemp'], capture_output=True)
|
|
|
|
p12file = cmd.output.strip()
|
|
|
|
|
|
|
|
try:
|
|
|
|
with NSSDatabase() as nssdb:
|
|
|
|
nssdb.create_db()
|
|
|
|
|
|
|
|
# 1. Test delete_key_and_cert when cert + key are present
|
|
|
|
# Create a NSS DB with cert + key
|
|
|
|
create_selfsigned(nssdb)
|
|
|
|
# Save both in a p12 file for latter use
|
|
|
|
ipautil.run(
|
|
|
|
[
|
|
|
|
'pk12util',
|
|
|
|
'-o', p12file, '-n', CERTNICK, '-d', nssdb.secdir,
|
|
|
|
'-k', nssdb.pwd_file,
|
|
|
|
'-w', nssdb.pwd_file
|
|
|
|
])
|
|
|
|
# Delete cert and key
|
|
|
|
nssdb.delete_key_and_cert(CERTNICK)
|
|
|
|
# make sure that everything was deleted
|
|
|
|
assert len(nssdb.list_keys()) == 0
|
|
|
|
assert len(nssdb.list_certs()) == 0
|
|
|
|
|
|
|
|
# 2. Test delete_key_and_cert when only key is present
|
|
|
|
# Import cert and key then remove cert
|
|
|
|
import_args = [
|
|
|
|
'pk12util',
|
|
|
|
'-i', p12file, '-d', nssdb.secdir,
|
|
|
|
'-k', nssdb.pwd_file,
|
|
|
|
'-w', nssdb.pwd_file]
|
|
|
|
ipautil.run(import_args)
|
|
|
|
nssdb.delete_cert(CERTNICK)
|
|
|
|
# Delete cert and key
|
|
|
|
nssdb.delete_key_and_cert(CERTNICK)
|
|
|
|
# make sure that everything was deleted
|
|
|
|
assert len(nssdb.list_keys()) == 0
|
|
|
|
assert len(nssdb.list_certs()) == 0
|
|
|
|
|
|
|
|
# 3. Test delete_key_and_cert when only cert is present
|
|
|
|
# Import cert and key then remove key
|
|
|
|
ipautil.run(import_args)
|
|
|
|
nssdb.delete_key_only(CERTNICK)
|
|
|
|
# make sure the db contains only the cert
|
|
|
|
assert len(nssdb.list_keys()) == 0
|
|
|
|
assert len(nssdb.list_certs()) == 1
|
|
|
|
|
|
|
|
# Delete cert and key when key is not present
|
|
|
|
nssdb.delete_key_and_cert(CERTNICK)
|
|
|
|
# make sure that everything was deleted
|
|
|
|
assert len(nssdb.list_keys()) == 0
|
|
|
|
assert len(nssdb.list_certs()) == 0
|
|
|
|
|
|
|
|
# 4. Test delete_key_and_cert with a wrong nickname
|
|
|
|
# Import cert and key
|
|
|
|
ipautil.run(import_args)
|
|
|
|
# Delete cert and key
|
|
|
|
nssdb.delete_key_and_cert('wrongnick')
|
|
|
|
# make sure that nothing was deleted
|
|
|
|
assert len(nssdb.list_keys()) == 1
|
|
|
|
assert len(nssdb.list_certs()) == 1
|
|
|
|
finally:
|
|
|
|
os.unlink(p12file)
|
2019-12-10 05:46:14 -06:00
|
|
|
|
|
|
|
|
|
|
|
def test_check_validity():
|
|
|
|
with NSSDatabase() as nssdb:
|
|
|
|
nssdb.create_db()
|
|
|
|
create_selfsigned(nssdb)
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
nssdb.verify_ca_cert_validity(CERTNICK)
|
|
|
|
nssdb.verify_server_cert_validity(CERTNICK, CERTSAN)
|
|
|
|
with pytest.raises(ValueError):
|
|
|
|
nssdb.verify_server_cert_validity(CERTNICK, 'invalid.example')
|