#893 subsystems (ca, kra, tks, tps) mixed-up their subsystem certs when sharing same Tomcat instance
Closed: Fixed None Opened 10 years ago by cfu.

This issue is discovered while working on https://fedorahosted.org/pki/ticket/862 TPS rewrite: provide connector
service for JAVA-based TPS subsystem .

It only occurs in situation when the subsystems share the same tomcat instance.
It seems whenever a connection is made, the ssl client auth cert ("subsystem cert") used for the connection gets inherited by the next connection, even if it's made by another subsystem.

To illustrate:
I have all 4 subsystems sharing one Tomcat instance. Now with my new connector code in TPS (#862), when I run a cli (for testing purpose) that would trigger a "renewal" op sent from TPS to CA, it works fine. The cert used for client-auth is TPS's subsystem cert. However, immediately after, if I try to issue a cert from CA agent page, which is a crmf request with key archival, itwould trigger a request sent directly form CA to KRA. The funny thing is, it would fail, and upon investigation, I found the ssl client cert used between ca and kra was the TPS's subsystem cert (trust me, all config are absolutely correct). And, if I started out issuing a crmf key archival that triggers CA to KRA first, then if I run cli to tps, it would trigger TPS to CA using the ca's subsystem cert.

I supposed we can make up the rule and say all of them have to share the same subsystem cert, but I think an investigation that provides an explanation would help us understand this shared model better.


my suggestion for handling this case would be to make it so that there are no individual subsystem certs created, but just sharing one single subsystem cert within the same tomcat instance.

I am seeing this exact same problem when connecting to the database using client auth in IPA.
In this case, there are two users: uid=dbuser, o=ipadrm and uid=dbuser,o=ipaca - each of which uses the subsystem cert for their respective subsystem.

In this case, I can see that the server is only presenting one of the certs for authentication.
Need to resolve this sooner rather than later as its holding me up.

Introduction

Ok, so I think the correct way to move forward on this is to use the same subsystem certificate in each subsystem in a shared instance.

Before explaining how this will work, let me explain how we currently use subsystem certs.
Subsystem certs are currently used in two ways:

  • They are used as authentication when one PKI subsystem talks to another. This is for system->system communications like the CA talking to the KRA through the KRA connector, or the TPS talking to the CA, TKS or DRM.
  • They are used to authenticate the pkidbuser, which is created at server configuration and can be used to communicate securely with a ldap database using client auth. This is actually used by IPA.

The exact details of what happens during configuration is as follows:

  • A subsystem certificate is generated for each subsystem.
  • When needed, a user is created on the target subsystem to facilitate inter-subsystem communications.
    So, for example, when the KRA is configured, a user is created on the KRA - uid=CA-<ca_host>-<ca_port>, ou=people, o=<kra basedn>, which contains the CA subsystem certificate. The CA presents this certificate when initiating communication with the KRA.
  • A user is created to communicate with the database. This user uid=pkidbuser, ou=people, o=<basedn> contains the subsystem cert and also has an attribute seeAlso, which contains the subjectDN of the certificate. This attribute is important. When the db is configured, it is expected that certmap.conf will be configured to check this attribute when matching the cert presented by the client.

The ticket describes the problems that occur when tomcat instances/databases are shared.

The basic outline of the proposed solution is as follows:

  • When a new subsystem is created, a system user will be created using the subsystem cert.
  • If the subsystems share a tomcat instance, then they will use the same subsystem certificate.
  • If the subsystems share the same tomcat instance and share the same database, then only one user will have the seeAlso attribute.

The details are in the cases below:

Case 1: shared tomcat instance and shared database

This is what we decided would be the default case. For sake of illustration, I will consider the installation of a CA and KRA, although this is extensible to the TPS interactions as well.

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The KRA is configured. In the configuration we specify:
    • shared_tomcat_instance=true
    • shared_db = True
    • subsystem_cert_subject_dn = <ca subsystem cert subject dn>
    • subsystem_cert_nick = < ca subsystem cert nick>
    • uid of CA dbuser -> uid=pkiSystemUser, ou=people, o=<ca basedn>
  • During KRA configuration,
    • A new subsystem cert is not created, Instead the nicks/entries in CS.cfg are obtained from the
      provided subsystem_nick
    • We create a new user uid=pkiSystemUser, ou=people, o=<kra basedn> with the provided subsystem cert retrieved from the specified nick.
    • This user is placed in the relevant agent groups. In the case of the CA->DRM, this must be a DRM agent group.
    • The new user does not have the seeAlso attribute. Because the db is shared, we expect that the db will resolve the CA dbuser when the subsystem cert is presented. We will ensure that the CA dbuser has the relevant acls to read the KRA entries.

Case 2: shared tomcat instance and non-shared database

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The KRA is configured. In the configuration we specify:
    • shared_tomcat_instance=true
    • shared_db = False
    • subsystem_cert_subject_dn = <ca subsystem cert subject dn>
    • subsystem_cert_nick = < ca subsystem cert nick>
  • During KRA configuration,
    • A new subsystem cert is not created, Instead the nicks/entries in CS.cfg are obtained from the
      provided subsystem_nick
    • We create a new user uid=pkiSystemUser, ou=people, o=<kra basedn> with the provided subsystem cert retrieved from the specified nick.
    • This user is placed in the relevant agent groups. In the case of the CA->DRM, this must be a DRM agent group.
    • The new user does have the seeAlso attribute and relevant acls. Because the db is not shared, we expect no complications when the subsystem contacts the db.

Case 3: Non shared tomcat instance

In this case, we expect the existing code to work just fine. Because the tomcat instance is not shared, there is no problem with SSL caching, and we do not share subsystem certs.

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The KRA is configured. In the configuration we specify:
    • shared_tomcat_instance=False
    • shared_db = False
  • During KRA configuration,
    • A new subsystem cert is created - and all config entries are updated as we currently do.
    • A new user uid=CA-<ca host>-<ca port>, ou=people, o=<kra basedb> is created with the CA subsystem cert and put in the relevant agent groups. This is exactly the same as existing code.
    • We create a new user uid=pkiSystemUser, ou=people, o=<kra basedn> with the new subsystem nick and seeAlso attribute. This user is used to communicate with the DB. This is identical to existing code, except that the user name has been changed from pkidbuser to pkiSystemUser

It is worth also discussing how this will work with the TPS. Things are a little different than the CA->KRA setup because the CA initiates contact with the KRA.

In the TPS case, because the TPS initiates connections with the CA, KRA and TKS, the TPS configuration code must call a servlet (registerUser) on each of those subsystems to create a user.

The TPS communicates with the CA, KRA and TKS in essentially the same way. I will describe the setup of the TPS->CA connection.

Case 1 - shared tomcat instance, shared DB

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The TPS is configured. In the configuration we specify:
    • shared_tomcat_instance=True
    • shared_db = True
    • subsystem_cert_subject_dn = <ca subsystem cert subject dn>
    • subsystem_cert_nick = < ca subsystem cert nick>
    • uid of CA dbuser -> uid=pkiSystemUser, ou=people, o=<ca basedn>
  • During TPS configuration,
    • A new subsystem cert is not created, Instead the nicks/entries in CS.cfg are obtained from the provided subsystem_nick
    • We call registerUser on the CA and provide a new query parameter: generateUser=False. As before, we pass in the subsystem cert.
    • On the CA, the relevant system user is looked up from the cert, and is added to the relevant agent groups.
    • We create a new user uid=pkiSystemUser, ou=people, o=<tps basedn> with the provided subsystem cert retrieved from the specified nick. At this point, this user isn't actually used for anything, but is there in case we ever need to initiate communications with the TPS.
    • The new user does not have the seeAlso attribute. Because the db is shared, we expect that the db will resolve the CA dbuser when the subsystem cert is presented. We will ensure that the CA dbuser has the relevant acls to read the TPS entries.

Case 2 : Shared tomcat instance, Non-shared DB

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The TPS is configured. In the configuration we specify:
    • shared_tomcat_instance=True
    • shared_db = False
    • subsystem_cert_subject_dn = <ca subsystem cert subject dn>
    • subsystem_cert_nick = < ca subsystem cert nick>
  • During TPS configuration,
    • A new subsystem cert is not created, Instead the nicks/entries in CS.cfg are obtained from the provided subsystem_nick
    • We call registerUser on the CA and provide a new query parameter: generateUser=False. As before, we pass in the subsystem cert.
    • On the CA, the relevant system user is looked up from the cert, and is added to the relevant agent groups.
    • We create a new user uid=pkiSystemUser, ou=people, o=<tps basedn> with the provided subsystem cert retrieved from the specified nick. This user does have the seeAlso attribute so that it can be used to communicate with the DB.

Case 3 - Non--shared tomcat instance

  • The CA is configured. A system user is created uid=pkiSystemUser, ou=people,o=<ca basedn> with the CA subsystem certificate and the seeAlso attribute. This user can be used to communicate with the DB.
  • The TPS is configured. In the configuration we specify:
    • shared_tomcat_instance=False
    • shared_db = False
  • During TPS configuration,
    • A new subsystem cert is created and the config is updated as normal.
    • We call registerUser on the CA and provide a new query parameter and pass in the subsystem cert. We will default generateUser to the previous behavior with is True.
    • On the CA, the new system user is added (with its cert) and is added to the relevant agent groups.
    • We create a new user uid=pkiSystemUser, ou=people, o=<tps basedn> with the provided subsystem cert retrieved from the specified nick. At this point, this user has the seeAlso attribute so it can be used to communicate with its db.

Just an update on the above.

Found that a new query parameters is not needed in the registerUser() call because we already check for the existence of a user with the provided cert. I probably added this code awhile back.

Pushed changes to master:

commit b834efbaa8c929c10cf00252b71ebc29e2f10456

Metadata Update from @cfu:
- Issue assigned to vakwetu
- Issue set to the milestone: 10.2 - 03/14 (March)

7 years ago

Dogtag PKI is moving from Pagure issues to GitHub issues. This means that existing or new
issues will be reported and tracked through Dogtag PKI's GitHub Issue tracker.

This issue has been cloned to GitHub and is available here:
https://github.com/dogtagpki/pki/issues/1460

If you want to receive further updates on the issue, please navigate to the
GitHub issue and click on Subscribe button.

Thank you for understanding, and we apologize for any inconvenience.

Login to comment on this ticket.

Metadata