OPC UA client/server protocol security is based on application certificates, each application shall trust each other. Determining if a certificate is trusted might include verification of a trust chain in cases that were not expected at first sight. This article explains how to validate a certificate to pass OPC UA certification 1 and hence how to configure correctly certificate validation to ensure your application certificate is accepted.
OPC UA protocol uses X.509 v3 Certificates to establish secure communication between OPC UA applications. On reception of an application certificate, this certificate shall be validated and be determined if the application is trusted prior to be used 2. The main validation steps are described in the OPC UA specification 3, we will focus on the trust chain, signature and trust list check steps specificities.
A certificate shall be signed by an issuer, it might be self-signed in which case the issuer and issued certificate are the same. Otherwise it is signed by a certificate issuer which shall be a certificate authority (CA).
In the first case, the only way to trust the application certificate is to directly consider the certificate as trusted since it is self-signed, thus the certificate shall be known prior to reception and already trusted. In the second case, it is possible to trust the CA that issued the certificate, thus any valid application certificate signed by this CA will be accepted as trusted. But you might still want to trust directly the application certificate issued by a CA but not the CA, in this latter case the trust chain to this certificate shall still be verified even if the CA is not configured as trusted.
The latter case might seem pretty uncommon and is not identifiable in the OPC UA specification referenced above, however management of this case is mandatory for OPC UA certification and is part of the test cases 4 (see cases 044 and 045).
We will now detail the validation process of the different cases presented. But first we should share the concepts involved precisely in the certificate validation process.
issuer certificate: a certificate signing a certificate as being trustworthy, the signed certificate is then an issued certificate.
issued certificate: a certificate signed by a certificate which should be a certificate authority or itself.
trusted issuer: a certificate authority (CA) which issued certificates are also trusted. All the certificates of the signing chain including the root CA must be provided.
trusted issued: a certificate issued by an untrusted CA or self-signed, it is configured as trustworthy.
accepted issued: a certificate issued by a trusted CA, it has been evaluated as trustworthy according to trust chain.
untrusted issuer: a certificate authority (CA) that is used to verify the signing chain of a trusted issued certificate. The difference with a trusted issuer is that certificates issued by the untrusted issuer are not automatically accepted.
The trusted issuer definition voluntarily excludes the certificates that are not CA, those are never considered as trusted issuers in the next sections.
The difference between trusted issuers and trusted issued certificates is that issued certificates are trusted on a one by one basis, whereas the trusted issuer may emit a large number of trusted certificates.
Each certificate involved is expected to declare its possible usage. Those properties are declared in certificate extensions through basic constraints 5 and key usages 6 7 . Thus for a certificate validation those properties are verified for each certificate type.
An issuer certificate shall declare to be a CA in its basic constraints to state it may be used to verify certificate signatures.
An issued certificate shall declare the following key usages in the context of OPC UA protocol :
Client/Server authentication, Digital signature and Non-repudiation : used for authentication and data integrity
Key encipherment: used to establish secure communication using symmetric encryption
Data encipherment: used to guarantee data confidentiality
In the particular case of a self-signed certificate the certificate is not required to be a CA.
When an application has a self-signed issued certificate, the trust chain and signature are limited to this single certificate. As a peer application receiving the certificate, we should accept this certificate only if it was already known as a trusted issued certificate. Therefore this approach requires to deploy certificate configuration for each application certificate we want to trust.
Thus if the certificate is trusted issued, only the certificate content remains to be verified by checking the following items:
security policy: signature algorithm and key lenghts are compatible with the OPC UA security policy.
validity period: the current time shall be after the start of the validity period and before the end.
hostname (server certificate only): URL used to connect to the server shall be the same as one of the hostnames specified in the server certificate.
URI: contains an application URI that shall match the URI specified in the
ApplicationDescriptionprovided with the certificate.
certificate usage: the certificate declared properties shall match the expected usage
If an application has an issued certificate that is not directly trusted, the issuer chain shall be verified and shall contain trusted issuers in order to accept the application certificate. The trust chain includes the direct CA issuer of the application certificate and recursively the CA issuer of each issuer until a root issuer (that should be self-signed).
Thus the certficate is accepted as trusted if for all certificates in the chain, starting from issued certificate until root issuer, verifications done for self-signed certificates succeeded and the following properties are also verified:
build certificate chain: the whole trust chain can be built.
signature: the certificate signature shall be valid, the signature is considered invalid if the signature issuer is unknown.
trust list check: if application certificate is not trusted, its issuer shall be trusted.
find revocation list: each CA certificate shall have a revocation list.
revocation check: the certificate shall not be revoked by its CA issuer revocation list.
If an application has a trusted issued certificate that is not self-signed, the certificate is already configured as trusted. However, the trust chain shall still be verified to be valid, even if issuers are not trusted. This is a way to guarantee the whole trust chain does not include invalid period or revoked certificate, moreover this is required for OPC UA certification (see test cases 044 and 045 4).
The verifications done for trusted issuers shall still succeed for the whole certificate chain except it is not necessary anymore to trust the issuers, i.e. the trust list check verification is not necessary anymore but other verifications are.
The certificate validation process is generally dedicated to a Public Key Infrastructure (PKI) component. Developping such a component for OPC UA application implies to have a good understanding of the OPC UA standard requirements and configuring it might also be a complex task depending on the expected certificate architecture.
The following figure sums up the main cases to deal with in such a PKI:
Cert C and Cert E are both refused because their respective issuer certificate is not declared to be a CA (see certificate properties). Moreoever in the case of Cert C, its issuer Cert A is unknown prior to validation.
Now you are aware of the possible certificate architectures that can be used to ensure acceptation of an application certificate, you can practice it using the PKI provider of the S2OPC open source OPC UA toolkit. This PKI provider was used to pass the OPC UA certification of S2OPC toolkit server. You can find some information on how to configure S2OPC toolkit to manage all those cases in the certificate validation configuration page and in the PKI documentation page.