On 07/29/2016 09:39 AM, Petr Spacek wrote:
On 27.7.2016 19:06, Ben Lipton wrote:
Hi all,

I think the automatic CSR generation feature
(https://fedorahosted.org/freeipa/ticket/4899,
http://www.freeipa.org/page/V4/Automatic_Certificate_Request_Generation) is
stable enough to review now. The following are summaries of the attached 
patches:
0004: LDAP schema changes for the new feature
0005: Basic API for new objects and CSR generation
0006: Update install automation to create some default mapping rules
0007: Implement the lookups and text processing that generates the CSR config
0008 and 0009: Implement some actual transformation rules so that the feature
is usable
0010: Add a new cert profile for user certs, with mappings
0011: Implement import/export of cert profiles with mappings
0012: Tests for profile import/export

Generally speaking, later patches depend on earlier ones, but I don't
anticipate any problems from committing earlier patches without later ones.

If you prefer, you can also comment on the pull request version:
https://github.com/LiptonB/freeipa/pull/4. Note that I may force push on this
branch.

Allocation of OIDs for schema change also needs review:
https://code.engineering.redhat.com/gerrit/#/c/80061/

Known issues:
- When the requested principal does not have some of the requested data,
produces funny-looking configs with extra commas, empty sections, etc. They
are still accepted by my copies of openssl and certutil, but they look ugly.
- The new objects don't have any ACIs, so for the moment only admin can run
the new commands.
- Does not yet have support for prompting user for field values, so currently
all data must come from the database.
- All processing happens on the server side. As discussed in a previous
thread, it would be desirable to break this out into a library so it could be
used client-side.

Very excited to hear your thoughts!
Hi Ben,

I wanted to give it a try from user's point of view first, before diving into
implementation details. Here are some observations:

Thanks for giving it a try! This is great feedback.

0. Design pages are using term "helper" and it is used even as option in the
example with smartcards. Please fix either design page or the code so they are
consistent.
Good point. In a previous discussion, Alexander remarked that --helper sounded too low-level, but I find that --use sounds very generic and --format doesn't make a lot of sense for ipa cert-request, which never actually gives you the config that's generated. So if they're all going to be the same word, which is probably a good idea, I might be leaning towards --helper, but I'm interested to hear opinions on this.

1. The "ipa cert-request" command is missing options --autofill and --use (aka
helper aka format :-) which are mentioned in the design pages.
Yeah, I haven't managed to implement much of the UI niceness suggested by the design page. I probably should have mentioned that in the email - all that I expect to be working at this point is 'ipa cert-get-requestdata' and CRUD for the mapping rules/profiles themselves.

2. "ipa cert_get_requestdata" command passes even without --profile-id and
generates empty config. I think that this is not expected :-)

More expected than you might think :) I'm guessing what's happening is that you're passing a user principal and it's defaulting to the caIPAserviceCert profile, then failing to fill out any of the fields because the data it needs is not there. I agree this isn't great. I was planning to address this by having it throw an error if it can't generate at least the subject of the request, and maybe suggest using a different profile.

I chose to have it default to caIPAserviceCert because that's what ipa cert-request does, but maybe that's not as predictable as I thought.

3. "ipa cert_get_requestdata --format=openssl" prints the text to stdout
including label "Configuration file contents:". This is hard to use because
simple redirection like "ipa cert_get_requestdata --format=openssl > config"
will not give you valid OpenSSL config file - it needs hand-editing.

It would be good to add --out parameter you envisioned in the design page.
Please ask jcholast for proper name and semantics :-) With --out option the
command can be used to generate valid config (or script if certutil was 
selected).
Agreed. Another example of the UI not being quite right yet. I've been unsure how to handle this, because of certutil taking a command line and openssl a config file. It actually gets even more complicated because, as you point out in the next item, openssl also needs a command in addition to the config file. I'm interested in thinking about how to handle this cleanly from a user perspective. Generating a script, or providing the command lines as hints, might be ways to get around these concerns.
4. "ipa cert_get_requestdata --format=openssl" could print hint what OpenSSL
command should be executed on the generated config file. For testing I've used
command "openssl req -new -out csr -text -config config" (stolen and modified
from smart card example). Also, as a second hint, it could print the IPA
command which needs to be used to sign the CSR generated by the helper.
Also agreed, the framework should be able to generate and (for purposes of 'ipa cert-request --autofill') even execute the command required to make the CSR.

5. My naive attempt to get userCert for admin failed:
$ ipa cert_get_requestdata --format=openssl --principal=admin
--profile-id=userCert > usercert.conf
# remove the trailing label
$ openssl req -new -out csr -text -config usercert.conf
$ ipa cert-request --principal=admin --profile-id=userCert usercert.csr
ipa: ERROR: invalid 'csr': No Common Name was found in subject of request.

I'm attaching files generated by the commands above. I did not modify anything
in the templates or profiles, just tried to use the new profile added by
freeipa-blipton-0010-Add-a-new-cert-profile-for-users.patch .

Hah! This is what I get for thinking I know what the output has to look like, and not testing all the way through to requesting the cert. I'll change the profile to generate a subject with CN= instead of UID=. Updated patch is attached. Unfortunately these rules are only updated at ipa-server-install time, so if you'd like to fix it without reinstalling:

ipa certtransformationrule-mod dataUsernameCN dataUsernameCertutil --template 'CN={{ipa.datafield(subject.uid.0)|quote}},{{ipa.datafield(config.ipacertificatesubjectbase.0)|quote}}' ipa certtransformationrule-mod dataUsernameCN dataUsernameOpenssl --template '{{ipa.datafield(config.ipacertificatesubjectbase.0)}}
CN={{ipa.datafield(subject.uid.0)}}'
Yes, that must be an actual linebreak between the subjectbase and the CN in the openssl one. I know :-/


Hopefully I will get to other things soon (but not this week).


Anyway, all this seems like (expected) initial problems. In general the first
touch with user interface seems reasonable and needs only small improvements.

Good work!


From 59bb98d29ab21912ef784acbacd37efaf61a448a Mon Sep 17 00:00:00 2001
From: Ben Lipton <blip...@redhat.com>
Date: Mon, 25 Jul 2016 18:48:13 -0400
Subject: [PATCH] Add a new cert profile for users

https://fedorahosted.org/freeipa/ticket/4899
---
 install/share/profiles/Makefile.am  |  1 +
 install/share/profiles/userCert.cfg | 97 +++++++++++++++++++++++++++++++++++++
 ipapython/dogtag.py                 | 30 ++++++++++++
 3 files changed, 128 insertions(+)
 create mode 100644 install/share/profiles/userCert.cfg

diff --git a/install/share/profiles/Makefile.am b/install/share/profiles/Makefile.am
index b5ccb6e9317a93c040b7de0e0bc1ca5cb88c33fc..2e0166b91e1c85fd734f325d1c7c77598ab4ff39 100644
--- a/install/share/profiles/Makefile.am
+++ b/install/share/profiles/Makefile.am
@@ -4,6 +4,7 @@ appdir = $(IPA_DATA_DIR)/profiles
 app_DATA =				\
 	caIPAserviceCert.cfg		\
 	IECUserRoles.cfg		\
+	userCert.cfg			\
 	$(NULL)
 
 EXTRA_DIST =				\
diff --git a/install/share/profiles/userCert.cfg b/install/share/profiles/userCert.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3c2eeb5af1cf7422d8d4dda233cfec463e848125
--- /dev/null
+++ b/install/share/profiles/userCert.cfg
@@ -0,0 +1,97 @@
+profileId=userCert
+classId=caEnrollImpl
+desc=This certificate profile is for enrolling user certificates with S/MIME key usage permitted
+visible=false
+enable=true
+enableBy=admin
+auth.instance_id=raCertAuth
+name=Manual User Dual-Use S/MIME capabilities Certificate Enrollment
+input.list=i1,i2
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,2,3,4,5,6,7,8,9,10
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=CN=[^,]+,.+
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=CN=$$request.req_subject_name.cn$$, $SUBJECT_DN_O
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=RSA
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.userCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.userCertSet.3.default.name=Key Default
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=http://$IPA_CA_RECORD.$DOMAIN/ca/ocsp
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.userCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.8.default.name=Signing Alg
+policyset.userCertSet.8.default.params.signingAlg=-
+policyset.userCertSet.9.constraint.class_id=noConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.userCertSet.9.default.name=Subject Key Identifier Extension Default
+policyset.userCertSet.9.default.params.critical=false
+policyset.userCertSet.10.constraint.class_id=noConstraintImpl
+policyset.userCertSet.10.constraint.name=No Constraint
+policyset.userCertSet.10.default.class_id=userExtensionDefaultImpl
+policyset.userCertSet.10.default.name=User Supplied Extension Default
+policyset.userCertSet.10.default.params.userExtOID=2.5.29.17
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index 8ad194daa06cebf07e3112d6a04fd7ea3bb7b159..326a21c20e793f54942fe3063c4d5c16c77beaf3 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -57,6 +57,12 @@ INCLUDED_PROFILES = (
             FieldMapping(u'syntaxSAN', [u'dataDNS']),
         ]),
     Profile(
+        u'userCert', u'Standard profile for users', True,
+        [
+            FieldMapping(u'syntaxSubject', [u'dataUsernameCN']),
+            FieldMapping(u'syntaxSAN', [u'dataEmail']),
+        ]),
+    Profile(
         u'IECUserRoles',
         u'User profile that includes IECUserRoles extension from request',
         True, []),
@@ -88,6 +94,19 @@ INCLUDED_MAPPING_RULESETS = (
                 [u'certutil']),
         ]),
     MappingRuleset(
+        u'dataUsernameCN',
+        u'DN with the principal\'s username as the CommonName',
+        [
+            TransformationRule(
+                u'dataUsernameOpenssl',
+                u'{{ipa.datafield(config.ipacertificatesubjectbase.0)}}\nCN={{ipa.datafield(subject.uid.0)}}',
+                [u'openssl']),
+            TransformationRule(
+                u'dataUsernameCertutil',
+                u'CN={{ipa.datafield(subject.uid.0)|quote}},{{ipa.datafield(config.ipacertificatesubjectbase.0)|quote}}',
+                [u'certutil']),
+        ]),
+    MappingRuleset(
         u'syntaxSAN', u'Syntax for adding a Subject Alternate Name',
         [
             TransformationRule(
@@ -109,6 +128,17 @@ INCLUDED_MAPPING_RULESETS = (
                 u'dataDNSCertutil', u'dns:{{ipa.datafield(subject.krbprincipalname.0|safe_attr("hostname"))|quote}}',
                 [u'certutil']),
         ]),
+    MappingRuleset(
+        u'dataEmail',
+        u'Constructs a SubjectAltName entry from the principal\'s email',
+        [
+            TransformationRule(
+                u'dataEmailOpenssl', u'email = {{ipa.datafield(subject.mail.0)}}',
+                [u'openssl']),
+            TransformationRule(
+                u'dataEmailCertutil', u'email:{{ipa.datafield(subject.mail.0)|quote}}',
+                [u'certutil']),
+        ]),
 )
 
 DEFAULT_PROFILE = u'caIPAserviceCert'
-- 
2.5.5

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to