Bug 1730363 - Users and groups should be able to revoke certs that they own
Summary: Users and groups should be able to revoke certs that they own
Keywords:
Status: NEW
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: ipa
Version: 7.6
Hardware: x86_64
OS: Linux
unspecified
medium
Target Milestone: rc
: ---
Assignee: Florence Blanc-Renaud
QA Contact: ipa-qe
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2019-07-16 14:19 UTC by dminnich
Modified: 2019-07-23 23:20 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:


Attachments (Terms of Use)
example crt (2.30 KB, text/plain)
2019-07-22 12:29 UTC, dminnich
no flags Details

Description dminnich 2019-07-16 14:19:02 UTC
Description of problem:
When a user creates a cert using IPA they are unable to revoke that cert. 




Version-Release number of selected component (if applicable):
ipa-server-4.6.4-10.el7_6.2.x86_64


How reproducible:
Always


Steps to Reproduce:

[root@shell01 3]# kinit rbac1test
Password for rbac1test@IPA.REDHAT.COM: 

[root@shell01 3]# MUSER=rbac1test

[root@shell01 3]# openssl req -newkey rsa:4096 -keyout ${MUSER}.key -new -sha256 -nodes -days 730 -subj "/emailAddress=${MUSER}@redhat.com/CN=${MUSER}/O=IPA.REDHAT.COM/UID=${MUSER},cn=users,cn=accounts,dc=ipa,dc=redhat,dc=com" -out ${MUSER}.csr && chmod 600 ${MUSER}.key
Generating a 4096 bit RSA private key
.........................................................................................++
.........................................++
writing new private key to 'rbac1test.key'
-----

[root@shell01 3]# ipa cert-request --profile-id=caIPAuserCert --ca=ipa --principal="${MUSER}@IPA.REDHAT.COM" ${MUSER}.csr --certificate-out=${MUSER}.crt
  Issuing CA: ipa
  Certificate: ...
  Subject: UID=rbac1test,CN=users,CN=accounts,DC=ipa,DC=redhat,DC=com,E=$request.auth_token.mail[0]$
  Issuer: CN=Certificate Authority,O=IPA.REDHAT.COM
  Not Before: Tue Jul 16 14:09:54 2019 UTC
  Not After: Fri Jul 16 14:09:54 2021 UTC
  Serial number: 12085
  Serial number (hex): 0x2F35


[dminnich@dminnichlt ~]$ ipa cert-show 0x2F35 --raw --all
  certificate: ..
  certificate_chain: ...
  certificate_chain: ..
  certificate_chain: ...
  certificate_chain: ..
  serial_number: 12085
  serial_number_hex: 0x2F35
  owner: uid=rbac1test,cn=users,cn=accounts,dc=ipa,dc=redhat,dc=com


[root@shell01 3]# ipa cert-revoke 0x2F35 --revocation-reason=0
ipa: ERROR: Insufficient access: not allowed to perform operation: revoke certificate


I do not want to give the user the "Revoke Certificate" permission which would allow them to revoke any certificate.  

IPA allows a kinited /etc/krb5.keytab host to revoke its cert but not other hosts certs.  I'd like to see the same thing for users.  

Perhaps checking "owner" on the cert entry or for certs stored in "certificate" in their record would allow for some authorization?


Actual results:
ipa: ERROR: Insufficient access: not allowed to perform operation: revoke certificate

Expected results:
Certificate revoked


Additional info:
We use a lot of mutual TLS authentication.  Allowing a development team to revoke and issue a new certificate when somebody leaves their team instead of reaching out to the centralized IAM team for the initial revoke would be a win.

Comment 2 Rob Crittenden 2019-07-16 14:25:42 UTC
How would you define own in this context?

Comment 3 dminnich 2019-07-16 15:43:19 UTC
Person that created the cert is enough for our current use case.  

I don't know enough about:
- principal aliases
- privilege delegation (as opposed to RBAC) 
- OK_TO_AUTH_AS_DELEGATE

to specify if things like that should also be listed as the owner of a cert. If so, maybe a "mangedby" style thing could be used.

Comment 4 Rob Crittenden 2019-07-16 15:47:16 UTC
What we do in the service cert case is ensure that the host in the subject matches the hostname. For a user case this sort of thing might be more challenging.

Comment 5 dminnich 2019-07-16 15:55:21 UTC
I'm not able to get a cert for rcritten when authed as dminnich and using the default profiles.  

Is the concern that somebody could establish a custom profile and say use First Last or Email in the subject and you won't be able to match that to username?

Comment 6 Fraser Tweedale 2019-07-18 00:31:57 UTC
(Making this comment public, and I will make some others public too; I see not reason for this
discussion to take place behind closed doors).

Here be dragons.

Short of proof of possession, I can only think of a few safe ways to allow user self-revoke.

1.1. Certificate has user's email address in SAN rfc822Name (unlikely because in many cases the CSR will not have asked for it).
1.2. Certificate has users's LDAP DN in SAN directoryName (very unlikely because there isn't really a use case, but IPA does support it).
1.3. Certificate subject DN is the users's LDAP DN (vanishingly unlikely; I can't even think of a way to do this through IPA).

Notably, there are some approaches which are not safe (alluded in earlier comments):

2.1. Certificate is present in user's userCertificate attribute.  Unsafe because user may have write access to that attribute and they could put anyone's certificate.
2.2. Validation based on CN; unsafe because there may be a collision with some other namespace.  Custom profiles necessarily make this too great a risk.

There are a couple of scenarios in which we might wish to grant revoke authority, but for which IPA and Dogtag
currently do not store the data required to make the decision.  These include:

3.1. The requesting principal is the subject principal of the original certificate request.
3.2. The requesting pricinpal is the operator principal of the original certificate request.

In the future it may be possible to answer these questions, but today and at least for the near future we cannot.

So we could implement item 1.1 (and perhaps 1.2. and 1.3. for completeness; it is not much extra work), and that would
support the use case with the caveat that the rfc822 name must be in the cert, and therefore must be included in the CSR.

Apart from that, proof of possession is the only reliable way to decide self-service revoke authority (as of 2019).
There would be a lot of work to implement a usable-by-humans PoP-based revocation mechanism, the benefit is unclear.
And of course it excludes some valid use cases (e.g. "whoops I deleted the key / forgot the passphrase").

Comment 7 Alexander Bokovoy 2019-07-18 08:03:39 UTC
Fraser,

we have also Kerberos principal in SAN, that can be used to map the request pretty reliably.

Comment 8 dminnich 2019-07-18 16:11:45 UTC
Notes from a few days ago makes me think that 
policyset.serverCertSet.1.default.params.name=UID=$request.req_subject_name.uid$    
would but the LDAP DN in the Subject for 1.3.   Obviously that would depend on people configuring it and not shooting themselves in the foot with a custom profile.  

Good points on the rest of the stuff.  The 3.x options sound the most secure.  

I don't think what what Alexander is mentioning comes out of the box either.  Is there equal fear that somebody could trample that with a custom profile?  Or could hard coded logic be inserted if it isn't already there so that if that SAN is created it is always the principal of the person asking for the cert?

Comment 9 Fraser Tweedale 2019-07-19 01:00:40 UTC
Good point Alexander.  The KRB5PrincipalName SAN otherName value, if present, is reliable.  Call that option 1.4.

Dustin, the config you suggest will only put the UID, not the whole DN.  And we don't validate the UID attribute,
only CN.  But if you use the following config:

  ...name=UID=$request.req_subject_name.cn$,CN=users,CN=accounts,DC=example,DC=com

(with correct DC attributes matching IDM base DN), then we have users's LDAP DN in the certificate subject
DN.  This is the condition of item 1.3 (so it turn out, it is possible... although I have not tested it
yet).  This would be easier, from user's point of view, than constructing a CSR with rfc822Name, directoryName or
KRB5PrincpialName value.

Could it be trampled with a custom profile?  Yes, but it is a very unlikely misconfiguration.

Options 3.x are indeed the most "secure" for some definition of security.  I would prefer to say they are
the least vulnerable to abuse / collisions.  But they are completely unattainable, based on the information
currently stored by IDM.

Comment 10 dminnich 2019-07-19 16:24:58 UTC
[dminnich@dminnichlt tmp]$ ipa certprofile-show caIPAuserCert --out=caIPAuserCertBZRFE.txt
[dminnich@dminnichlt tmp]$ grep request.req caIPAuserCertBZRFE.txt 
policyset.serverCertSet.1.default.params.name=UID=$request.req_subject_name.uid$,CN=users,CN=accounts,DC=ipa,DC=redhat,DC=com,OU=employee
[dminnich@dminnichlt tmp]$ ipa certprofile-import caIPAuserCertBZRFE --store=true --file=caIPAuserCertBZRFE.txt --desc="bugzilla 1730363"

[root@shell01 client-cert]# MUSER=rbac1test
[root@shell01 4]# openssl req -newkey rsa:4096 -keyout ${MUSER}.key -new -sha256 -nodes -days 730 -subj "/emailAddress=${MUSER}@redhat.com/UID=${MUSER}/CN=${MUSER}" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=email:copy")) -out ${MUSER}.csr
[root@shell01 client-cert]# ipa cert-request --profile-id=caIPAuserCertBZRFE --ca=ipa --principal="${MUSER}@IPA.REDHAT.COM" ${MUSER}.csr --certificate-out=${MUSER}.crt
... 
 Serial number (hex): 0x30C4




[root@shell01 client-cert]# openssl x509 -in rbac1test.crt -text | grep Subje
        Subject: OU=employee, DC=com, DC=redhat, DC=ipa, CN=accounts, CN=users/UID=rbac1test

[root@shell01 client-cert]# ipa cert-revoke 0x30C4 --revocation-reason=0
ipa: ERROR: Insufficient access: not allowed to perform operation: revoke certificate


That look as expected?

Comment 11 Fraser Tweedale 2019-07-22 03:06:08 UTC
The failure to revoke is totally expected, because there is no self-service revocation
technique implemented at this time.

Dustin, I'm not sure what the DN structure is without the raw certificate data (PEM file).
OpenSSL pretty-print can sometimes be confusing.  But there are a couple of issues, outlined below.

Putting:

  policyset.serverCertSet.1.default.params.name=UID=$request.req_subject_name.uid$,CN=users,CN=accounts,DC=ipa,DC=redhat,DC=com

(specifically "$request.req_subject_name.uid$") is not the right way, because IPA does not validate the UID attribute
in the CSR, only the CN attribute.  So this is putting unvalidated data in the certificate (DANGER!)
Instead you should put a configuration like:

  policyset.serverCertSet.1.constraint.class_id=noConstraintImpl   
  policyset.serverCertSet.1.constraint.name=No Constraint                  
  policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl     
  policyset.serverCertSet.1.default.name=Subject Name Default              
  policyset.serverCertSet.1.default.params.name=UID=$request.req_subject_name.cn$,cn=users,cn=accounts,dc=ipa,dc=local

Note "$request.req_subject_name.cn$" in above snippet.

The OU=employee part is problematic if you want to do a full DN match (approach 1.3).  I understand
it is there for a use case that requires such a thing, but it's not compatible with approach 1.3.
But you can use the "OU in Subject" DN technique alongside 1.1, 1.2 or 1.4 without a problem.

Comment 12 dminnich 2019-07-22 12:27:58 UTC
Thanks for the response.  I knew it wouldn't work.  But thought I'd show a before and eventual after  as well as the Subject.    

I changed things to match what you suggest in 1.3 and uploaded the pem.  

[dminnich@dminnichlt tmp]$ grep request.req caIPAuserCertBZRFE.txt
policyset.serverCertSet.1.default.params.name=UID=$request.req_subject_name.cn$,CN=users,CN=accounts,DC=ipa,DC=redhat,DC=com



I do need that OU=employee thing.  Well, I guess I need something that server operators can do additional AuthZ on.  I don't know the landscape of mutual TLS client libraries but my guess is more of them would support validations in Subject vs something in a SAN or a custom certificate extension or similar.  So keeping that in the subject and moving the full DN of a user into a SAN for IPA revocation authz seems like a better approach.  

I like the concept of 1.2 and 1.4 more than 1.1.  The full DN is more unique and specific than an email address.  Will end users need to properly craft CSRs for 1.2 and 1.4 or can a profile figure out who is making the request in IPA and shove that data into the right place safely?

Comment 13 dminnich 2019-07-22 12:29:29 UTC
Created attachment 1592582 [details]
example crt

Comment 14 Fraser Tweedale 2019-07-23 03:56:01 UTC
> I like the concept of 1.2 and 1.4 more than 1.1.  The full DN is more unique and specific than an email address.
> Will end users need to properly craft CSRs for 1.2 and 1.4 or can a profile figure out who is making the request
> in IPA and shove that data into the right place safely?

Dustin, in IPA there is no way yet (maybe one day, but changes in how IPA talks to Dogtag would be needed first).
In Dogtag it is possible only with custom plugins (i.e. not supported).


Note You need to log in before you can comment on or make changes to this bug.