Configuring SAF certificates and keyrings for TLS on the z/OS operating system

Migrate an existing collective to use System Authorization Facility (SAF) for security-related functions, such as requests for authentication, authorization, or certificates.

Before you begin

Mark the collective certificates that are used for administrative security with a defined string for the controller and member. For example, assume that the distinguished name (DN) of your certificate is as follows:
DN=<hostname>, O=IBM, OU=Collective
Configure the rdn attribute with the "OU=Collective" string from the distinguished name in the server.xml file:
<collectiveCertificate rdn="OU=Collective"></collectiveCertificate>

About this task

Separate certificate authority signers (CA) distinguish the Collective controller from a member. With SAF, the controller trusts the members and members trust the controller.

The Organizational Unit (OU), OU('Collective'), component of the Subject Distinguished Name defines the string and marks the certificate to be recognized for the following procedure.

In the sample RACF® commands that follow, CONTROL is the RACF user ID of the controller and MEMBER is the RACF user ID of the member.

Procedure

  1. Create SAF certificates and a keyring for the controller.
    1. Create a collective controller CA (CERTAUTH) certificate.
      RACDCERT CERTAUTH GENCERT SUBJECTSDN(CN('CONTROLLER ROOT')
      O('IBM') C('US'))SIZE(2048)WITHLABEL('CONTROLLER ROOT')
      TRUST NOTAFTER(DATE(2035/12/31))
    1. Create a server certificate for the collective controller that is signed by the collective controller CA.
      Important: Replace the text of controller.host.name with the controller host name to avoid a host name mismatch with the browser URL.
      RACDCERT ID(CONTROL) GENCERT SUBJECTSDN(CN('controller.host.name')
      O('IBM') OU('Collective')) WITHLABEL('CONTROLLER')
      SIGNWITH(CERTAUTH LABEL('CONTROLLER ROOT')) SIZE(2048)
      NOTAFTER(DATE(2020/12/30))
               
    2. Create a keyring for the collective controller.
      RACDCERT ID(CONTROL) ADDRING(CONTROL.KEYRING)
    3. Connect the collective controller CA to the controller keyring.
      RACDCERT CONNECT(CERTAUTH LABEL('CONTROLLER ROOT')
      RING(CONTROL.KEYRING))ID(CONTROL)
    4. Connect the controller server certificate to the controller keyring.
      RACDCERT CONNECT(ID(CONTROL) LABEL('CONTROLLER')
      RING(CONTROL.KEYRING)) ID(CONTROL)  
  2. Create SAF certificates and a keyring for the member.
    1. Create a collective member CA (CERTAUTH) certificate.
      RACDCERT CERTAUTH GENCERT SUBJECTSDN(CN('MEMBER ROOT')
      O('IBM') C('US'))SIZE(2048)WITHLABEL('MEMBER ROOT')
      TRUST NOTAFTER(DATE(2035/12/31))
    2. Connect the collective member CA to the controller keyring.
      RACDCERT CONNECT(CERTAUTH LABEL('MEMBER ROOT')
      RING(CONTROL.KEYRING))ID(CONTROL)
    3. Create a server certificate for the collective member that is signed by the collective member CA.
      Important: Replace the text of member.host.name with the member host name to avoid a host name mismatch with the browser URL.
      RACDCERT ID(MEMBER) GENCERT SUBJECTSDN(CN('member.host.name')
        O('IBM') OU('Collective')) WITHLABEL('MEMBER')
        SIGNWITH(CERTAUTH LABEL('MEMBER ROOT')) SIZE(2048)
        NOTAFTER(DATE(2020/12/30))
      
    4. Create a keyring MEMBER.KEY for the collective member.
      RACDCERT ID(MEMBER) ADDRING(MEMBER.KEY)
    5. Connect the collective member CA to the MEMBER.KEY keyring.
      RACDCERT CONNECT(CERTAUTH LABEL('MEMBER ROOT')
      RING(MEMBER.KEY)) ID(MEMBER)
              
    6. Connect the member server cert to the MEMBER.KEY keyring.
      RACDCERT CONNECT(ID(MEMBER) LABEL('MEMBER')
      RING(MEMBER.KEY)) ID(MEMBER)
    7. List the member keyring.

      You should see two certificates in the keyring.

      RACDCERT ID(MEMBER) LISTRING(MEMBER.KEY)
      Digital ring information for user MEMBER:
             >MEMBER.KEY<
        Certificate Label Name             Cert Owner     USAGE      DEFAULT
        --------------------------------   ------------   --------   -------
        MEMBER ROOT                        CERTAUTH       CERTAUTH     NO
      
        MEMBER                             ID(MEMBER)     PERSONAL     NO
      
      
    8. Create a second keyring MEMBER.TRUST for the member.
      RACDCERT ID(MEMBER) ADDRING(MEMBER.TRUST)
    9. Connect the collective controller CA to the MEMBER.TRUST keyring.
      RACDCERT CONNECT(CERTAUTH LABEL('CONTROLLER ROOT')
      RING(MEMBER.TRUST))ID(MEMBER)
    10. List the MEMBER.TRUST keyring. You should see one certificate in the keyring.
      RACDCERT ID(MEMBER) LISTRING(MEMBER.TRUST)
      Digital ring information for user MEMBER:
        Ring:
             >MEMBER.TRUST<
        Certificate Label Name             Cert Owner     USAGE      DEFAULT
        --------------------------------   ------------   --------   -------
        CONTROLLER ROOT                    CERTAUTH       CERTAUTH     NO
      
      
  3. List the controller keyring. You should see three certificates in the keyring.
    RACDCERT ID(CONTROL)LISTRING(CONTROL.KEYRING) 
    Ring:
           >CONTROL.KEYRING<
      Certificate Label Name             Cert Owner     USAGE      DEFAULT
      --------------------------------   ------------   --------   -------
      MEMBER ROOT                        CERTAUTH       CERTAUTH     NO
    
      CONTROLLER ROOT                    CERTAUTH       CERTAUTH     NO
    
      CONTROLLER                         ID(CONTROL)    PERSONAL     NO
    
  4. Give the controller and member the authority to use the keyrings and certificates that they own.

    You can use FACILITY class profiles or RDATALIB profiles.

    The following example uses the FACILITY class permissions for the CONTROL and MEMBER users:

    PERMIT IRR.DIGTCERT.LIST CLASS(FACILITY) ID(CONTROL MEMBER) ACCESS(READ)
    PERMIT IRR.DIGTCERT.LISTRING CLASS(FACILITY) ID(CONTROL MEMBER) ACCESS(READ)
    SETR RACLIST(FACILITY) REFRESH

    The following example uses the for RDATALIB class permissions for the CONTROL and MEMBER users:

    PERMIT CONTROL.**.LST CLASS(RDATALIB) ID(CONTROL) ACCESS(READ)
    PERMIT MEMBER.**.LST CLASS(RDATALIB) ID(MEMBER) ACCESS(READ)
    SETR RACLIST(RDATALIB) REFRESH
  5. Add the z/OS® security feature to the controller and member serverl.xml files.
    1. Stop the controller and member. Save a copy of each of the server.xml files for the controller and member to your backup files.
    2. Continue to edit the server.xml files. In the controller and member server.xml files, add the following features to the featureManager element:
      <feature>transportSecurity-1.0</feature>
      <feature>zosSecurity-1.0</feature>
            
    3. Create a server class profile so the controller and member can access SAF services. See Enabling z/OS authorized services on Liberty for z/OS in the product documentation. Then, in the controller and member server.xml files, replace the following line:
      <quickStartSecurity userName="admin" userPassword="adminpw" />
      with the following five lines:
      <safAuthorization id="saf" racRouteLog="ASIS" />
      <safCredentials profilePrefix="BBGZDFLT" unauthenticatedUser="WSGUEST"/>
      <safRegistry id="saf" realm="WASRealm" />
      <safRoleMapper profilePattern="%profilePrefix%.%role%" />
      <zosLogging enableLogToMVS="true"></zosLogging>

      The EJBROLE profile that controls access to the Admin Center is BBGZDFLT.Administrator.

    4. In the controller and member server.xml files, specify the collectiveCertificate string by adding the following line:
      <collectiveCertificate rdn="OU=Collective"></collectiveCertificate>
  6. In the controller server.xml file, replace the keyfile names with SAF keyring names.
    1. Locate the keystore element with the defaultKeyStore ID.
      Replace location="${server.config.dir}/resources/security/key.jks"/> with the following lines:
      location="safkeyring:///CONTROL.KEYRING"
      type="JCERACFKS" fileBased="false" readOnly="true" />
    2. Locate the keystore element with the defaultTrustStore ID.
      Replace location="${server.config.dir}/resources/security/trust.jks"/> with the following lines:
      location="safkeyring:///CONTROL.KEYRING"
      type="JCERACFKS" fileBased="false" readOnly="true" />  
    3. Locate the keystore element with the serverIdentity ID.
      Replace location="${server.config.dir}/resources/collective/serverIdentity.jks"/> with the following lines:
      location="safkeyring:///CONTROL.KEYRING"
      type="JCERACFKS" fileBased="false" readOnly="true" />
          
    4. Locate the keystore element with the collectiveTrust ID.
      Replace location="${server.config.dir}/resources/collective/collectiveTrust.jks"/> with the following lines:
      location="safkeyring:///CONTROL.KEYRING"
      type="JCERACFKS" fileBased="false" readOnly="true" />
          

      Do not change the collectiveRootKeys keystore element.

  7. In the member server.xml file, replace the keyfile names with SAF keyring names.
    1. Locate the keystore element with the defaultKeyStore ID.
      Replace location="${server.config.dir}/resources/security/key.jks"/> with the following lines:
      location="safkeyring:///MEMBER.KEY"
      type="JCERACFKS" fileBased="false" readOnly="true" />
    2. Locate the keystore element with the defaultTrustStore ID.
      Replace location="${server.config.dir}/resources/security/trust.jks"/> with the following lines:
      location="safkeyring:///MEMBER.TRUST"
      type="JCERACFKS" fileBased="false" readOnly="true" />  
    3. Locate the keystore element with the serverIdentity ID.
      Replace location="${server.config.dir}/resources/collective/serverIdentity.jks"/> with the following lines:
      location="safkeyring:///MEMBER.KEY"
      type="JCERACFKS" fileBased="false" readOnly="true" />
          
    4. Locate the keystore element with the collectiveTrust ID.
      Replace location="${server.config.dir}/resources/collective/collectiveTrust.jks"/> with the following lines:
      location="safkeyring:///MEMBER.TRUST"
      type="JCERACFKS" fileBased="false" readOnly="true" />
          
  8. Start the controller and member.