ipatests: CA ACL and cert profile functional test

https://fedorahosted.org/freeipa/ticket/57

Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
Milan Kubík 2015-09-22 15:22:25 +02:00 committed by Martin Basti
parent d2ff5e4639
commit 5ab0fcabf3
2 changed files with 344 additions and 0 deletions

View File

@ -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

View File

@ -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)