summaryrefslogtreecommitdiffstats
path: root/ipatests/test_xmlrpc
diff options
context:
space:
mode:
authorMilan KubĂ­k <mkubik@redhat.com>2015-09-22 15:22:25 +0200
committerMartin Basti <mbasti@redhat.com>2015-10-27 09:57:48 +0100
commit5ab0fcabf3e6ac7970c1803893717301a4b4cfe8 (patch)
treedbbf101a30b9aaa2b0e4e37d0a154d7fe755bcdd /ipatests/test_xmlrpc
parentd2ff5e4639157a839fe7d3c36b462e2195c32f4a (diff)
downloadfreeipa-5ab0fcabf3e6ac7970c1803893717301a4b4cfe8.tar.gz
freeipa-5ab0fcabf3e6ac7970c1803893717301a4b4cfe8.tar.xz
freeipa-5ab0fcabf3e6ac7970c1803893717301a4b4cfe8.zip
ipatests: CA ACL and cert profile functional test
https://fedorahosted.org/freeipa/ticket/57 Reviewed-By: Martin Basti <mbasti@redhat.com>
Diffstat (limited to 'ipatests/test_xmlrpc')
-rw-r--r--ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl108
-rw-r--r--ipatests/test_xmlrpc/test_caacl_profile_enforcement.py236
2 files changed, 344 insertions, 0 deletions
diff --git a/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
new file mode 100644
index 000000000..da94c25e5
--- /dev/null
+++ b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
@@ -0,0 +1,108 @@
+auth.instance_id=raCertAuth
+classId=caEnrollImpl
+desc=Certificate for S-MIME extension
+enable=true
+enableBy=ipara
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.list=i1,i2
+name=SMIME certificate profile
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.constraint.params.pattern=CN=refuse sign
+policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=CN=$request.req_subject_name.cn$, O={iparealm}
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.range=740
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=731
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=http://ipa-ca.{ipadomain}/ca/ocsp
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
+policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.9.constraint.name=No Constraint
+policyset.serverCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.serverCertSet.9.default.name=CRL Distribution Points Extension Default
+policyset.serverCertSet.9.default.params.crlDistPointsCritical=false
+policyset.serverCertSet.9.default.params.crlDistPointsEnable_0=true
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0=CN=Certificate Authority,o=ipaca
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0=DirectoryName
+policyset.serverCertSet.9.default.params.crlDistPointsNum=1
+policyset.serverCertSet.9.default.params.crlDistPointsPointName_0=http://ipa-ca.{ipadomain}/ipa/crl/MasterCRL.bin
+policyset.serverCertSet.9.default.params.crlDistPointsPointType_0=URIName
+policyset.serverCertSet.9.default.params.crlDistPointsReasons_0=
+policyset.serverCertSet.10.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.10.constraint.name=No Constraint
+policyset.serverCertSet.10.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.10.default.name=Subject Key Identifier Extension Default
+policyset.serverCertSet.10.default.params.critical=false
+policyset.serverCertSet.11.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.11.constraint.name=No Constraint
+policyset.serverCertSet.11.default.class_id=userExtensionDefaultImpl
+policyset.serverCertSet.11.default.name=User Supplied Extension Default
+policyset.serverCertSet.11.default.params.userExtOID=2.5.29.17
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11
+visible=false
diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
new file mode 100644
index 000000000..e9472b078
--- /dev/null
+++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
@@ -0,0 +1,236 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
+#
+
+import os
+import pytest
+import tempfile
+
+from ipalib import api, errors
+from ipatests.util import (
+ prepare_config, unlock_principal_password, change_principal)
+from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
+from ipatests.test_xmlrpc.test_certprofile_plugin import CertprofileTracker
+from ipatests.test_xmlrpc.test_caacl_plugin import CAACLTracker
+
+from ipapython.ipautil import run
+
+BASE_DIR = os.path.dirname(__file__)
+
+SMIME_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime.cfg.tmpl')
+SMIME_MOD_CONSTR_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime-mod.cfg.tmpl')
+CERT_OPENSSL_CONFIG_TEMPLATE = os.path.join(BASE_DIR, 'data/usercert.conf.tmpl')
+CERT_RSA_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'data/usercert-priv-key.pem')
+
+
+CERT_SUBJECT_BASE = (
+ api.Command.config_show()
+ ['result']['ipacertificatesubjectbase'][0]
+)
+
+SMIME_USER_INIT_PW = u'Change123'
+SMIME_USER_PW = u'Secret123'
+
+
+def generate_user_csr(username, domain=None):
+ csr_values = dict(
+ ipacertbase=CERT_SUBJECT_BASE,
+ ipadomain=domain if domain else api.env.domain,
+ username=username)
+
+ with tempfile.NamedTemporaryFile(mode='w') as csr_file:
+ run(['openssl', 'req', '-new', '-key', CERT_RSA_PRIVATE_KEY_PATH,
+ '-out', csr_file.name,
+ '-config', prepare_config(
+ CERT_OPENSSL_CONFIG_TEMPLATE, csr_values)])
+
+ with open(csr_file.name, 'r') as f:
+ csr = unicode(f.read())
+
+ return csr
+
+
+@pytest.fixture(scope='class')
+def smime_profile(request):
+ profile_path = prepare_config(
+ SMIME_PROFILE_TEMPLATE,
+ dict(ipadomain=api.env.domain, iparealm=api.env.realm))
+
+ tracker = CertprofileTracker(u'smime', store=True,
+ desc=u"S/MIME certificate profile",
+ profile=profile_path)
+
+ return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def smime_acl(request):
+ tracker = CAACLTracker(u'smime_acl')
+
+ return tracker.make_fixture(request)
+
+
+# TODO: rewrite these into Tracker instances
+# UserTracker has problems while setting passwords.
+# Until fixed, will use this fixture.
+@pytest.fixture(scope='class')
+def smime_user(request):
+ username = u'alice'
+ api.Command.user_add(uid=username, givenname=u'Alice', sn=u'SMIME',
+ userpassword=SMIME_USER_INIT_PW)
+
+ unlock_principal_password(username, SMIME_USER_INIT_PW, SMIME_USER_PW)
+
+ def fin():
+ api.Command.user_del(username)
+ request.addfinalizer(fin)
+
+ return username
+
+
+@pytest.fixture(scope='class')
+def smime_group(request):
+ api.Command.group_add(u'smime_users')
+
+ def fin():
+ api.Command.group_del(u'smime_users')
+ request.addfinalizer(fin)
+
+ return u'smime_users'
+
+
+class TestCertSignMIME(XMLRPC_test):
+
+ def test_cert_import(self, smime_profile):
+ smime_profile.ensure_exists()
+
+ def test_create_acl(self, smime_acl):
+ smime_acl.ensure_exists()
+
+ def test_add_profile_to_acl(self, smime_acl, smime_profile):
+ smime_acl.add_profile(certprofile=smime_profile.name)
+
+ # rewrite to trackers, prepare elsewhere
+ def test_add_user_to_group(self, smime_group, smime_user):
+ api.Command.group_add_member(smime_group, user=smime_user)
+
+ def test_add_group_to_acl(self, smime_group, smime_acl):
+ smime_acl.add_user(group=smime_group)
+
+ def test_sign_smime_csr(self, smime_profile, smime_user):
+ csr = generate_user_csr(smime_user)
+ with change_principal(smime_user, SMIME_USER_PW):
+ api.Command.cert_request(csr, principal=smime_user,
+ profile_id=smime_profile.name)
+
+
+class TestSignWithDisabledACL(XMLRPC_test):
+
+ def test_import_profile_and_acl(self, smime_profile, smime_acl):
+ smime_profile.ensure_exists()
+ smime_acl.ensure_missing()
+ smime_acl.ensure_exists()
+
+ def test_add_profile_to_acl(self, smime_acl, smime_profile):
+ smime_acl.add_profile(certprofile=smime_profile.name)
+
+ # rewrite to trackers, prepare elsewhere
+ def test_add_user_to_group(self, smime_group, smime_user):
+ api.Command.group_add_member(smime_group, user=smime_user)
+
+ def test_add_group_to_acl(self, smime_group, smime_acl):
+ smime_acl.add_user(group=smime_group)
+
+ def test_disable_acl(self, smime_acl):
+ smime_acl.disable()
+
+ def test_signing_with_disabled_acl(self, smime_acl, smime_profile,
+ smime_user):
+ csr = generate_user_csr(smime_user)
+ with change_principal(smime_user, SMIME_USER_PW):
+ with pytest.raises(errors.ACIError):
+ api.Command.cert_request(
+ csr, profile_id=smime_profile.name,
+ principal=smime_user)
+
+ def test_admin_overrides_disabled_acl(self, smime_acl, smime_profile,
+ smime_user):
+ csr = generate_user_csr(smime_user)
+ api.Command.cert_request(
+ csr, profile_id=smime_profile.name,
+ principal=smime_user)
+
+
+class TestSignWithoutGroupMembership(XMLRPC_test):
+
+ def test_import_profile_and_acl(self, smime_profile, smime_acl):
+ smime_profile.ensure_exists()
+ smime_acl.ensure_missing()
+ smime_acl.ensure_exists()
+
+ def test_add_profile_to_acl(self, smime_acl, smime_profile):
+ smime_acl.add_profile(certprofile=smime_profile.name)
+
+ def test_add_group_to_acl(self, smime_group, smime_acl, smime_user):
+ # smime user should not be a member of this group
+ #
+ # adding smime_user fixture to ensure it exists
+ smime_acl.add_user(group=smime_group)
+
+ def test_signing_with_non_member_principal(self, smime_acl, smime_profile,
+ smime_user):
+
+ csr = generate_user_csr(smime_user)
+ with change_principal(smime_user, SMIME_USER_PW):
+ with pytest.raises(errors.ACIError):
+ api.Command.cert_request(
+ csr,
+ profile_id=smime_profile.name,
+ principal=smime_user)
+
+ def test_admin_overrides_group_membership(self, smime_acl, smime_profile,
+ smime_user):
+ csr = generate_user_csr(smime_user)
+ api.Command.cert_request(
+ csr, profile_id=smime_profile.name,
+ principal=smime_user)
+
+
+class TestSignWithChangedProfile(XMLRPC_test):
+ """ Test to verify that the updated profile is used.
+
+ The profile change requires different CN in CSR
+ than the one configured. This leads to rejection
+ based on not meeting the profile constraints.
+ """
+
+ def test_prepare_env(self, smime_profile, smime_acl):
+ smime_profile.ensure_exists()
+ smime_acl.ensure_exists()
+
+ smime_acl.add_profile(certprofile=smime_profile.name)
+
+ def test_prepare_user_and_group(self, smime_group, smime_user, smime_acl):
+ api.Command.group_add_member(smime_group, user=smime_user)
+ smime_acl.add_user(group=smime_group)
+
+ def test_modify_smime_profile(self, smime_profile):
+ updated_profile_path = prepare_config(SMIME_MOD_CONSTR_PROFILE_TEMPLATE,
+ dict(
+ ipadomain=api.env.domain,
+ iparealm=api.env.realm))
+
+ with open(updated_profile_path) as f:
+ updated_profile = unicode(f.read())
+
+ updates = {u'file': updated_profile}
+ update_smime_profile = smime_profile.make_update_command(updates)
+ update_smime_profile()
+
+ def test_sign_smime_csr(self, smime_profile, smime_user):
+ csr = generate_user_csr(smime_user)
+ with change_principal(smime_user, SMIME_USER_PW):
+ with pytest.raises(errors.CertificateOperationError):
+ api.Command.cert_request(csr, principal=smime_user,
+ profile_id=smime_profile.name)