Package com.avaya.clientservices.provider.certificate

## Class CertificateManager

- java.lang.Object
- - com.avaya.clientservices.provider.certificate.CertificateManager

-     public class CertificateManager
      extends java.lang.Object

  Certificate manager class allows application developers to configure and make use of the library's client/server certificate trust validation logic. It allows specification of a client identity certificate, configure a private trust store and certificate trust validation of all the connections, application is making on its own.

  The developers can use the `setCertificates(X509Certificate[])` method to create a private trust store. It (private trust store) is an application managed certificate store that contains the Root and Intermediate CA certificates trusted (known as "trusted anchors") by an application. The private trust store is used to validate the server/client certificate chain for all the secure connections made by an application.

  The private trust store has following advantages over the conventional system certificate stores provided by Operating System -

  - The private trust store offers a sandbox certificate store exclusively used and managed by an application.
  - The trusted anchors (certificates) in the private trust store are not shared with trusted anchors from system certificate store.
  - Application administrators choose to distribute only necessary trusted CA certificates in a controlled way, not worrying for any rouge CA certificate being added to the private trust store.
  - Application can create and delete the private trust store without affecting the system certificate stores and thus affecting other connection-oriented applications.

  The private trust store allows application to be more secure. For example, consider a scenario where a CA inadvertently had issued certificates and revoked those later on. CA publishes the certificate status information so that application may choose to query and proceed. However, revocation status check process has its own challenges making it unsuitable, causing the rouge servers to be trusted by an applications. Such cases can be easily managed by using the private trust store. Application administrator may simply remove the corresponding CA certificate that had issued invalid certificates such that insecure connections cannot be established with the server.

  This class allows an application to store a client identity certificate which can be used to pass on to the server upon server's request during TLS Mutual Authentication. A client identity certificate is trust validated by the server and untrusted certificate will be rejected by the server by issuing SSL Alert and severing the connection.

  The client applications can register a certificate status listener to get notified when client identity certificate is about to expire. This notification serves as a reminder for an user to begin requesting a renewed certificate for this application. This notification period can be configured using `SecurityPolicyConfiguration`.

  Applications that have been using default certificate trust validation logic, can now delegate the trust validation request to this class. The certificate validation methods offered by this class allows the use of the private trust store or system trust store. Also, certain behavior of these methods can be preconfigured based on the application deployment scenarios via `SecurityPolicyConfiguration`.

  See Also:
    `HostnameValidator`

- - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `addCertificateStatusListener​(CertificateStatusListener listener)` | Registers a status listener to get notified about client identity certificate's expiration status.
    `void` | `deleteCertificateStore()` | Deletes an existing private trust store.
    `void` | `deleteClientIdentityCertificateChain()` | Deletes provisioned client identity certificate and private key.
    `void` | `dispose()` | Disposes the Certificate Manager's native object.
    `void` | `enroll​(ScepConfiguration configuration, EnrollmentCredentialProvider credentialProvider, CertificateEnrollmentCompletionHandler completionHandler)` | Request client identity certificate enrollment.
    `java.security.cert.X509Certificate[]` | `getCertificates()` | Returns certificates stored in the private trust store.
    `java.security.KeyStore` | `getClientIdentityAsPKCS12KeyStore​(char[] password)` | Returns a Java Keystore of PKCS12 type containing client identity certificate (chain) and a private key.
    `java.security.cert.X509Certificate` | `getClientIdentityCertificate()` | Returns a provisioned client identity certificate.
    `java.security.cert.X509Certificate[]` | `getClientIdentityCertificateChain()` | Returns a complete client identity certificate chain.
    `java.security.PrivateKey` | `getClientPrivateKey()` | Returns a private key associated with a client identity certificate chain.
    `boolean` | `isCertificateStoreInUse()` | Returns the private trust store status.
    `void` | `removeCertificateStatusListener​(CertificateStatusListener listener)` | Removes a certificate status listener.
    `void` | `setCertificates​(java.security.cert.X509Certificate[] trustedAnchors)` | Creates the private trust store using supplied trusted anchors (Root and Intermediate CA certificates).
    `void` | `setClientIdentityCertificateChain​(java.security.cert.X509Certificate[] chain, java.security.PrivateKey privateKey)` | Set client identity certificate chain to be used during TLS mutual authentication.
    `void` | `validateCertificates​(java.security.cert.X509Certificate[] chain, boolean overridePrivateTrustStore, CertificateValidationCompletionHandler completionHandler)` | Performs a trust validation of a certificate chain to determine if the secure connection with the peer can be trusted.
    `void` | `validateCertificates​(java.security.cert.X509Certificate[] chain, CertificateValidationCompletionHandler completionHandler)` | Validate the certificate chain against the active trust store.
    `void` | `validateCertificates​(java.security.cert.X509Certificate[] chain, java.lang.String expectedServiceDomain, java.lang.String expectedHostname, int port, boolean overridePrivateTrustStore, CertificateValidationCompletionHandler completionHandler)` | Validate server certificates.
    `void` | `validateCertificates​(java.security.cert.X509Certificate[] chain, java.lang.String expectedServiceDomain, java.lang.String expectedHostname, int port, CertificateValidationCompletionHandler completionHandler)` | Performs a trust validation of a certificate chain to determine if the secure connection with the peer can be trusted.

    - ### Methods inherited from class java.lang.Object

      `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Method Detail

    - #### addCertificateStatusListener

          public void addCertificateStatusListener​(CertificateStatusListener listener)

      Registers a status listener to get notified about client identity certificate's expiration status.

      Client application must implement `CertificateStatusListener.onCertificateExpiryNotification(X509Certificate, int)` method to get notified of client certificate's status.

      Parameters:
        `listener` - Listener to notify when interested event occurs.

    - #### removeCertificateStatusListener

          public void removeCertificateStatusListener​(CertificateStatusListener listener)

      Removes a certificate status listener. The client applications can use this method to stop receiving the client identity certificate expiration notifications.
      Parameters:
        `listener` - Listener to remove.

    - #### isCertificateStoreInUse

          public boolean isCertificateStoreInUse()

      Returns the private trust store status. This method can be used to determine if a client application has successfully created its own trust store or if it already exists.
      Returns:
        `true` if the private trust store exists, `false` when it is unavailable.

    - #### setCertificates

          public void setCertificates​(java.security.cert.X509Certificate[] trustedAnchors)
                               throws AppCertificateStoreException,
                                      java.security.cert.CertificateEncodingException

      Creates the private trust store using supplied trusted anchors (Root and Intermediate CA certificates).

      The private trust store is created if one does not already exist. Unlike system certificate stores, the client application can configure only one trust store. The Root and Intermediate CA certificates can be added while creating the trust store and cannot be modified, any such subsequent attempts are returned with an error.

      To modify the trusted anchors, the existing private trust store must be deleted and replaced with a new trust store using the new certificates.

      Parameters:
        `trustedAnchors` - CA certificates trusted by the client application.
      Throws:
        `AppCertificateStoreException` - Thrown when existing trust store is being recreated or modified.
        `java.security.cert.CertificateEncodingException` - Thrown when given certificate is invalid or corrupted.
      See Also:
        `deleteCertificateStore()`, `isCertificateStoreInUse()`

    - #### getCertificates

          public java.security.cert.X509Certificate[] getCertificates()
                                                               throws AppCertificateStoreNotInUseException

      Returns certificates stored in the private trust store.

      This method returns an array of `X509Certificate` stored in the private trust store only. An attempt to retrieve certificates from system certificate store results into `AppCertificateStoreNotInUseException` being thrown. Client applications can use this method for informative purpose, for example, displaying the existing trusted anchors (CA certificates) to its users.

      Returns:
        An array of `X509Certificate`; a value `null` for any failures during certificate retrieval.
      Throws:
        `AppCertificateStoreNotInUseException` - Thrown when private trust store is not available.
      See Also:
        `isCertificateStoreInUse()`

    - #### deleteCertificateStore

          public void deleteCertificateStore()
                                      throws AppCertificateStoreNotInUseException

      Deletes an existing private trust store.

      Client application can delete an existing private trust store if it wants to modify the certificates or it wants to rely on the system certificate stores supplied by the operating system.

      This method deletes the private trust store only.

      Throws:
        `AppCertificateStoreNotInUseException` - Thrown when private trust store is not available.

    - #### validateCertificates

          public void validateCertificates​(java.security.cert.X509Certificate[] chain,
                                           CertificateValidationCompletionHandler completionHandler)

      Validate the certificate chain against the active trust store.

      While establishing a secure connection with the peer, the certificate chain received as part of SSL handshake can be subjected to trust validation using this method. This method performs trust validation asynchronously and upon finished processing the validation result is notified via supplied completion handler.

      Unlike `validateCertificates(X509Certificate[], CertificateValidationCompletionHandler)` , this method allows client application to supply various hostname identifiers to be used while performing hostname validation (server identity validation). The client application that wants to use service type identifier to validate the hostname can pass empty `expectedHostname` value. The parameters `expectedServiceDomain` and `expectedHostname` are mutually exclusive.

      To learn more about the trust validate and hostname validation rules, see `validateCertificates(X509Certificate[], CertificateValidationCompletionHandler)`

      Parameters:
        `chain` - Certificate chain received from the peer during SSL handshake.
        `completionHandler` - A callback interface used to receive the validation result.
      See Also:
        `validateCertificates(X509Certificate[], String, String, int, CertificateValidationCompletionHandler)`

    - #### validateCertificates

          public void validateCertificates​(java.security.cert.X509Certificate[] chain,
                                           boolean overridePrivateTrustStore,
                                           CertificateValidationCompletionHandler completionHandler)

      Performs a trust validation of a certificate chain to determine if the secure connection with the peer can be trusted.

      This method provides a behavior to use platform certificate store to be used instead of the private trust store, if available.

      Parameters:
        `chain` - Certificate chain received from the peer during SSL handshake.
        `overridePrivateTrustStore` - Set to use system trust store for certificate validation by overriding the private trust store, if available.
        `completionHandler` - A callback interface used to receive the validation result.
      See Also:
        `validateCertificates(X509Certificate[], CertificateValidationCompletionHandler)`

    - #### validateCertificates

          public void validateCertificates​(java.security.cert.X509Certificate[] chain,
                                           java.lang.String expectedServiceDomain,
                                           java.lang.String expectedHostname,
                                           int port,
                                           CertificateValidationCompletionHandler completionHandler)

      Performs a trust validation of a certificate chain to determine if the secure connection with the peer can be trusted.

      While establishing a secure connection with the peer, the certificate chain received as part of SSL handshake can be subjected to trust validation using this method. This method performs trust validation asynchronously and upon finished processing the validation result is notified via supplied completion handler.

      If the private trust store is available, the certificate chain is completely built using the appropriate certificates (trusted anchors) from private trust store only and not other certificate stores are used. If private trust store is not available (or created), then this method uses the trusted anchors from system trust store. This method does not fallback or shares these stores in order to find the trusted anchors, each stores are treated as "exclusive".

      As part of the trust validation, the method also performs extended hostname validation (server identity validation) by matching different identifiers as explained below. The configured hostname is internally supplied by each "Service" or "Provider" calling this method.

      Depending upon the results, the client application can choose to ignore the hostname validation result by setting `SecurityPolicyConfiguration.setContinueOnTlsServerIdentityFailure(boolean)` to `true` prior to validation, which is not a good security practice and strongly not recommended.

      The hostname is matched as per the following order of identifiers:

      1. The match is performed against identifiers like DNS name and IP address from certificate's subject alternative names (SAN) attribute.
      2. Common Name (CN) from leaf certificate's Subject attribute.

      For SIP service domains, a full match is performed against URI and DNS parameters value from Subject Alternative Name attribute.

      A partial DNS domain names or Common Names match is supported with the use of Wildcard certificates. As per the RFC 5922, SIP service type matching is not supported for Wildcard certificates.

      Following hostname matching rules are applied to Wildcard certificates -

      - The match is performed at a single level sub-domain.
        `*.example.com` matches with `foo.example.com`
        `*.*.example.com` does not match with `foo.bar.example.com`
      - Internet TLDs (Top Level Domains) do not match.
        `*.com` does not match with `example.com` `*.co.in` does not match with `example.co.in`
      - Partial domain name match is not supported.
        `f*.example.com` does not match with `foo.example.com`
      - Partial matching for SIP service domain is not supported.

      On the current platform, the certificate chain is not checked for certificate's revocation status.

      Overall certificate trust validation result is obtained via `CertificateValidationException.getValidationResult()`.
      Parameters:
        `chain` - Certificate chain received from the peer during SSL handshake.
        `expectedServiceDomain` - Service domain string including service type identifier (e.g. sip:example.com) to use for hostname validation.
        `expectedHostname` - Hostname string to use for hostname validation.
        `port` - A peer listening port.
        `completionHandler` - A callback interface used to receive the validation result.
      See Also:
        `CertificateValidationCompletionHandler`, `CertificateValidationException`, `CertificateValidationResult`, `SecurityPolicyConfiguration`

    - #### validateCertificates

          public void validateCertificates​(java.security.cert.X509Certificate[] chain,
                                           java.lang.String expectedServiceDomain,
                                           java.lang.String expectedHostname,
                                           int port,
                                           boolean overridePrivateTrustStore,
                                           CertificateValidationCompletionHandler completionHandler)

      Validate server certificates.

      This method provides a behavior to use platform certificate store to be used instead of the private trust store, if available.

      Parameters:
        `chain` - Server certificate chain being subjected to validation.
        `expectedServiceDomain` - expected service domain.
        `expectedHostname` - expected host name.
        `port` - port value.
        `overridePrivateTrustStore` - Set to use system trust store for certificate validation by overriding the private trust store, if available.
        `completionHandler` - A callback interface used to receive the validation result.
      See Also:
        `validateCertificates(X509Certificate[], CertificateValidationCompletionHandler)`

    - #### setClientIdentityCertificateChain

          public void setClientIdentityCertificateChain​(java.security.cert.X509Certificate[] chain,
                                                        java.security.PrivateKey privateKey)
                                                 throws java.security.cert.CertificateEncodingException,
                                                        AppCertificateStoreException,
                                                        java.security.InvalidKeyException

      Set client identity certificate chain to be used during TLS mutual authentication.

      A client identity certificate identifies each client and generally issued unique to every client. This certificate is sent to the server upon request during the mutual authentication process as part of the SSL Handshake. Client application can use this method to set a certificate (or a chain, created using supporting certificates) and associated private key.

      Commonly client identity certificate and a private key are distributed as PKCS#12 file. Client applications can parse open the PKCS#12 file to know about the certificates and a key. Client application must delete an existing (if available) client identity certificate before setting the new one.

      The provisioned client certificate will be used for all the secure connections client application is making on its own. Client identity certificates per connection type (VoIP, Messaging, Collaboration etc.) is not supported.

      This method supports private keys created using RSA algorithm only.

      Parameters:
        `chain` - Client identity certificate chain
        `privateKey` - Unencrypted RSA private key.
      Throws:
        `java.security.cert.CertificateEncodingException` - Thrown when certificate(s) cannot be parsed or is corrupted.
        `AppCertificateStoreException` - Thrown when client certificate store already exists or encountered failure during provisioning the certificate.
        `java.security.InvalidKeyException` - Thrown for unsupported (non-RSA) private key algorithm.
      See Also:
        `deleteClientIdentityCertificateChain()`

    - #### getClientIdentityCertificate

          public java.security.cert.X509Certificate getClientIdentityCertificate()

      Returns a provisioned client identity certificate.

      Client application can retrieve the client identity certificate provisioned. This method returns only a leaf certificate and not an entire certificate chain, if provisioned.

      This method is suitable to use for informative purpose where application users can learn about various certificate details.

      Returns:
        Leaf certificate as X509Certificate; `null` if the certificate is not provisioned.
      See Also:
        `setClientIdentityCertificateChain(X509Certificate[], PrivateKey)`

    - #### deleteClientIdentityCertificateChain

          public void deleteClientIdentityCertificateChain()
                                                    throws CertificateStoreException

      Deletes provisioned client identity certificate and private key.

      Client application can modify the client certificate by deleting an existing the certificate using this method and setting a newer one.

      Throws:
        `CertificateStoreException` - Thrown when client certificate is not provisioned.

    - #### getClientIdentityCertificateChain

          public java.security.cert.X509Certificate[] getClientIdentityCertificateChain()

      Returns a complete client identity certificate chain.

      This helper method can be used to retrieve complete certificate chain to be used to create KeyStore or to inject into various SSL managers.

      Returns:
        An array of X509Certificate; `null` if certificates are not provisioned or corrupted.
      See Also:
        `getClientPrivateKey()`

    - #### getClientPrivateKey

          public java.security.PrivateKey getClientPrivateKey()

      Returns a private key associated with a client identity certificate chain.

      This helper method can be used to retrieve complete certificate chain to be used to create Keystore or to inject into various SSL managers.

      Returns:
        RSA Private key if provisioned, `null` otherwise.
      See Also:
        `getClientIdentityCertificateChain()`

    - #### getClientIdentityAsPKCS12KeyStore

          public java.security.KeyStore getClientIdentityAsPKCS12KeyStore​(char[] password)
                                                                   throws java.security.KeyStoreException

      Returns a Java Keystore of PKCS12 type containing client identity certificate (chain) and a private key.

      Client application can use this helper method to get the client identity certificates as a Keystore to inject directly into SSL managers. The certificates can be retrieved using `av-identity` alias.

      Parameters:
        `password` - Password to use while creating PKCS#12 keystore.
      Returns:
        Keystore with certificate chain and a private key.
      Throws:
        `java.security.KeyStoreException` - Thrown for PKCS#12 keystore creation failure.

    - #### enroll

          public void enroll​(ScepConfiguration configuration,
                             EnrollmentCredentialProvider credentialProvider,
                             CertificateEnrollmentCompletionHandler completionHandler)

      Request client identity certificate enrollment.
      Parameters:
        `configuration` - Enrollment configuration.
        `credentialProvider` - Enrollment credential provider used to request the certificate common name and enrollment password from the client.
        `completionHandler` - The completion handler for this operation.

    - #### dispose

          public void dispose()

      Disposes the Certificate Manager's native object.