1 Scope

This document provides the definition of GTA API profiles as introduced by ISO/IEC TS 30168 to facilitate the use of security information on SecureElements from OPC UA applications.

Example applications are:

authentication, verification, and establishment of security associations for OPC UA communication

user authentication

OPC Foundation

OPC is the interoperability standard for the secure and reliable exchange of data and information in the industrial automation space and in other industries. It is platform independent and ensures the seamless flow of information among devices from multiple vendors. The OPC Foundation is responsible for the development and maintenance of this standard.

OPC UA is a platform independent service-oriented architecture that integrates all the functionality of the individual OPC Classic specifications into one extensible framework. This multi-layered approach accomplishes the original design specification goals of

Platform independence: from an embedded microcontroller to cloud-based infrastructure

Secure: encryption, authentication, authorization, and auditing

Extensible: ability to add new features including transports without affecting existing applications

Comprehensive information modelling capabilities: for defining any model from simple to complex

DIN

DIN (Deutsches Institut für Normung), German Institute for Standardization, is the independent platform for standardization in Germany and worldwide. As a partner for industry, research and society as a whole, DIN plays a major role in helping innovations to reach the market in areas such as the digital economy or society, often within the framework of research projects. More than 36000 experts from industry, research, consumer protection and the public sector bring their expertise to work on standardization projects managed by DIN. The results of these efforts are market-oriented standards and specifications that promote global trade, encouraging rationalization, quality assurance and environmental protection as well as improving security and communication. For more information, go to www.din.de.

2 Normative references

The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments and errata) applies

ISO/IEC TS 30168, Internet of Things (IoT) - Generic Trust Anchor Application Programming Interface for Industrial IoT Devices

https://www.iso.org/standard/53288.html

OPC 10000-1, OPC Unified Architecture - Part 1: Overview and Concepts

http://www.opcfoundation.org/documents/10000-1/

OPC 10000-2, OPC Unified Architecture - Part 2: Security Model

http://www.opcfoundation.org/documents/10000-2/

OPC 10000-4, OPC Unified Architecture - Part 4: Services

http://www.opcfoundation.org/documents/10000-4/

OPC 10000-6, OPC Unified Architecture - Part 6: Mappings

http://www.opcfoundation.org/documents/10000-6/

OPC 10000-12, OPC Unified Architecture - Part 12: Discovery and Global Services

http://www.opcfoundation.org/documents/10000-12/

OPC 10000-21, OPC Unified Architecture - Part 21: Device Onboarding

http://www.opcfoundation.org/documents/10000-21/

3 Terms, abbreviated terms and conventions

3.1 Overview

It is assumed that basic concepts of OPC UA security and ISO/IEC TS 30168 are understood in this document. For the purposes of this document, the terms and definitions given in OPC 10000-1, OPC 10000-2, OPC 10000-4, OPC 10000-6, OPC 10000-12 and OPC 10000-21 as well as the following apply.

Note that OPC UA terms and terms defined in this document are italicized in the document.

3.2 SecureElements for OPC UA based on ISO/IEC TS 30168 terms

3.2.1 generic trust anchor application programming interface (GTA API)

set of well-defined methods, functions, routines, or commands for application software to facilitate the programming languages use of cryptographic or protected resources from an SE that is used as trust anchor

3.2.2 Personality

set of trusted information and cryptographic key material that is used by an application in a specific security context

3.2.3 Certificate

digitally signed data structure that contains a public key and the identity of a Client or Server.
[SOURCE: OPC 10000-1]

3.2.4 SecureElement (SE)

component capable of securely hosting functionalities, or confidential and cryptographic data, or both in accordance with well-defined rules and security requirements

3.2.5 TrustAnchor

3.3 Abbreviated terms

GTA APIGeneric Trust Anchor Application Programming Interface
SANSubject Alternative Name (X.509)
SESecure Element
URIUniform Resource Identifier

4 General information to ISO/IEC TS 30168 (GTA API) and OPC UA

4.1 OPC UA Security Object Model

A CertificateGroup is a context that contains a TrustList and one or more CertificateTypes that can be assigned to an Application (See OPC 10000-12).

This ObjectType allows an Application which has multiple TrustLists and/or ApplicationInstance Certificates to express them in its AddressSpace.

Figure 1 depicts the OPC UA security object model.

Figure 1 – OPC UA Security Object Model

4.2 ISO/IEC TS 30168 Concepts and OPC UA

ISO/IEC TS 30168 provides an API that addresses the integration of TrustAnchor functionality into an industrial IoT application. Typical requirements are:

Confidentiality and integrity protection of cryptographic credentials, e.g., private keys, pre-shared secret keys, passcodes

Integrity protection of trusted information, e.g., certificates trusted in the process of certification path validation

Protection of device configuration

4.2.1 SecureElements

A SecureElement is a component which is capable to securely store confidential or cryptographic data and host functionality to operate with that data. Thus, TrustAnchor capabilities can be realized using such a component. SecureElements are available with different characteristics and formfactors. Starting from software implementations bootstrapped from a single (hardware-) protected secret and offering some basic protection during execution (e.g., dedicated privilege level) to dedicated security micro controllers. Examples for trust anchor technologies are TCG DICE, TCG TPM, ISO 7816 series.

GTA API aims at providing a single generic abstraction allowing an application to access TrustAnchor functionality regardless of the technology used for the SecureElement.

4.2.2 Identifiers and Personalities

Figure 2 gives an overview of the GTA API information model. The starting point for objects organized by the GTA API information model are identifiers (cf. ISO/IEC TS 30168 clause 5.5.3). An identifier is used to identify a device or application in a specific security context. For example, with OPC UA an ApplicationUri is a suitable identifier.

Figure 2 – GTA API personality object model

Personalities are means that allow to present the device or application identity associated to an identifier in the digital world. A personality comprises all security objects which are needed to act in a given security context. The different security objects are represented as attributes of the personality:

  • Secret Attributes: These are objects which are typically used to proof the identity and authenticity of an entity or to access data which shall only be exposed to a designated entity. The SecureElement provides capabilities to protect the integrity, authenticity, and confidentiality of these objects. Examples are, private keys for asymmetric crypto, secret keys, and passcodes. In case of OPC UA this corresponds to an RSA or ECC private key (depending on the SecurityPolicy).

  • Trusted Attributes: These are objects which are typically used to proof the identity and authenticity of another entity. The SecureElement provides capabilities to protect the integrity and authenticity of these objects. Examples are, trusted public keys, trusted certificates, passcode verifiers.

  • Attributes: These are additional objects which can be managed by GTA API to provide a single point of information for objects belonging to the security context. These attributes can also be used to enable organization and discovery of personalities. However, these attributes do not depend on the security capabilities of the SecureElement. Examples are end entity and intermediate certificates, application specific information like labels or URIs.

4.2.3 GTA API and OPC UA object model mapping

  • Figure 3 shows how the OPC UA object model is mapped to the GTA API object model.

  • Each OPC UA Application is represented by a distinct Identifier in the GTA API object model. To express this relation the Identifier value is set to either the ProductInstanceUri or ApplicationUri (cf. 4.3.2.1).

  • The GTA API object model does not provide an equivalent for CertificateGroup. With GTA API a set of personalities are used to represent each CertificateGroup. The affiliation of these Personalities to a CertificateGroup is indicated by following respective naming conventions (cf. 4.3.2.2).

  • Each Certificate Group consists of multiple Personalities:

	Personality Identity: This personality represents the Device or Application as identified by its Device Identity Certificate or Application Instance Certificate. The Personality encloses the private key used for crypto operations (gta_authenticate_data_detached(), gta_unseal_data()). The Device Identity Certificate or Application Instance Certificate may be stored as an attribute.One or more Identity Personalities can exist in parallel, e.g., for different cryptographic profiles.
	Personality TrustList: This Personality is used to protect the OPC UA TrustList objects. The actual objects are not stored by GTA API. Instead the TrustList personality makes use of the basic GTA API profile for local data protection ch.iec.30168.basic.local_data_integrity_only as defined in ISO/IEC TS 30168 Annex B.2. The management of the OPC UA TrustList objects (trustedCertificates, trustedCrls, issuerCertificates, issuerCrls) is left to the OPC UA application.
	The integrity protection for the TrustList object using the profile ch.iec.30168.basic.local_data_integrity_only can be done in two ways:
	Using gta_authenticate_data_detached(), gta_verify_data_detached(): gta_authenticate_data_detached() produces a seal on the object to be protected. The seal is then stored along-side the original object. The seal can be verified using gta_verify_data_detached() to proof that the object has not been tampered with.
	Using gta_seal_data (), gta_unseal_data: gta_seal_data() creates an envelope containing the object to be protected. The object can be retrieved from the envelop using gta_unseal_data(). The envelope ensures that the contained object has not been tampered with.

Whether the first or second approach is more suitable depends on whether it is preferred to have an additional tag/seal for protection that needs to be handled by the application while the original object stays untouched, or to replace the original object with the protected object.

4.3 GTA API object identification and naming conventions for OPC UA

4.3.1 General

Each OPC UA application on a device corresponds to a GTA API identifier and at least one personality set. An OPC UA application may use multiple identity personalities corresponding to multiple SecurityPolicies.

Subsection 4.3.2 introduces conventions to be used for GTA API identifiers and personality names being used by OPC UA applications.

The personality’s application property and personality attributes can be used to provide additional distinguishing features depending on the actual personality type. Subsections 4.3.3, 4.3.4, and 4.3.5 provide an in-depth description for three types of personality sets which are commonly used in OPC UA:

DeviceIdentity Personality set: The personalities representing the DeviceIdentity and corresponding to DeviceIdentity certificates available for the onboarding process. DeviceIdentity Personalities are provided by the device vendor and can be used by OPC UA but are not managed by OPC UA.

DCA Personality set: The personalities representing the DCA and corresponding to the DCA certificate(s) and the corresponding Trust List.

Application Instance Personality set(s): Any other personality representing an OPC UA Application Instance corresponding to an Application Instance certificate(s) and the corresponding Trust List.

4.3.2 Naming Conventions

As described in 4.2.2 the main organization criteria for objects used with GTA API are identifiers and personality names. To allow easy retrieval of the required personality by an OPC UA application the following naming conventions shall be observed.

4.3.2.1 GTA API identifiers
GTA API identifiers created for exclusive use by OPC UA shall be of type org.opcfoundation.product_instance_uri or org.opcfoundation.application_instance_uri and their respective value shall be set to the ProductInstanceUri or ApplicationUri respectively.
Adhering to this convention allows convenient enumeration of all personalities belonging to a specific ProductInstanceUri or ApplicationUri using gta_personality_enumerate() or direct selection of a personality using its personality name.
4.3.2.2 GTA API personalities
GTA API personality names shall be set to an URI query string<InstanceUri>?cg=<CertificateGroup>[&ct=<CertificateType>&ix=<GenerationIndex>]

where

<InstanceUri> is either the ProductInstanceUri or the ApplicationUri

<CertificateGroup> is the Name portion of the BrowseName for the OPC UA CertificateGroup (e.g., “DefaultApplicationGroup”), and
<CertificateType> is the Name portion of the BrowseName for the OPC UA CertificateType (See OPC 10000-12) where any trailing “ApplicationCertificateType” is removed, “EccNistP256ApplicationCertificateType” → “EccNistP256”

<GenerationIndex> is a monotonically increasing number that can be used to distinguish between different versions of the personality. Multiple versions can exist during an update process which takes time to complete.

CertificateType and GenerationIndex are not present for the personality representing the TrustList for the CertificateGroup.

4.3.3 DeviceIdentity Personality

DeviceIdentity personalities are established by the device vendor, device integrator, or device distributor. Depending on the underlying device life-cycle and trust model, a DeviceIdentity may be represented by either an IDevID or LDevID. Especially IDevIDs are not intended for exclusive use by OPC UA. Figure 4 shows the object model for a DeviceIdentity Personality.

Figure 4 – DeviceIdentity Personality

The decision on the GTA API identifier type and value is left to the device vendor.

The personality name and application are also selected by the vendor.

To support the decision on whether a specific personality is eligible for OPC UA device onboarding, DeviceIdentity personalities should have an attribute of type org.opcfoundation.product_instance_uri. If present, the value of that attribute shall be set to the ProductInstanceUri.
"urn:some-company.com:2025-01:model-xyz:snr-16273849"

If this attribute is not present, the personality to be used as DeviceIdentity needs to be communicated to the DCA by other means (out-of-band).

The DeviceIdentity Certificate itself can be made available using a personality attribute of type ch.iec.30168.trustlist.certificate.self.x509. As the security of the DeviceIdentity Certificate does not depend on additional protection offered by a secure element it may also be stored elsewhere.

4.3.4 DCA Personality Set

DCA related Personalities are the first GTA API objects created for OPC UA. There would be one DCA TrustList Personality and one or more DCA Identity Personalities (corresponding to one or more DCA certificates). Figure 5 shows the object model for a DCA Personality Set.

Figure 5 – DCA Personality Set
By convention the identifier used to create DCA related Personalities shall be of type org.opcfoundation.application_instance_uri. The ProductInstanceUri is a natural choice for the identifier value used for the DCA Personality set. However, selection of the identifier value is left to the operator.
The application of a DCA Identity Personality shall be set to “DCA Identity” and the application of a DCA TrustList Personality shall be set to “DCA TrustList”. This allows easy selection of the DCA related Personalities using gta_personality_enumerate_application() (cf. ISO/IEC TS 30168, clause 6.6.10.4.12) during later use.

The name of the DCA Identity Personality is set according to the description in 4.3.2.2.

urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=Rsa2048&ix=1
urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=EccNistP256&ix=10
The DCA Certificate itself can be made available using a personality attribute of type ch.iec.30168.trustlist.certificate.self.x509. As the security of the DCA Certificate does not depend on additional protection offered by a secure element it may also be stored elsewhere.

The name of the TrustList personality is set according to the description in 4.3.2.2.

urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup

4.3.5 Application Instance Personality Set

Figure 6 shows the object model for an Application Instance Personality Set.

Figure 6 – Application Instance Personality set
GTA API identifiers used as a base to create personalities representing Application Instance Certificates for OPC UA applications should be of type org.opcfoundation.application_instance_uri and the value should be set to the ApplicationUri.
urn:manufacturer.com:2024-10:myproduct:myappid?cg=DefaultApplicationGroup

The name of an Application Instance Identity personality is set according to the description in 4.3.2.2. The names used for GTA API personalities representing Application Instance Certificates should be a qualified name with the namespace URI equal to the ApplicationUri. The qualified name used for the personality name can contain additional information to distinguish between multiple personalities sharing a single identifier.

urn:manufacturer.com:2024-10:myproduct:myappid?cg=DefaultApplicationGroup&ct=Rsa2048&ix=12
urn:manufacturer.com:2024-10:myproduct:myappid?cg=DefaultApplicationGroup&ct=EccNistP256&ix=14
The ApplicationInstance Certificate itself can be made available using a personality attribute of type ch.iec.30168.trustlist.certificate.self.x509. As the security of the Application Identity Certificate does not depend on additional protection offered by a secure element it may also be stored elsewhere.

The name of the TrustList personality is set according to the description in 4.3.2.2.

urn:manufacturer.com:2024-10:myproduct:myappid?cg=DefaultApplicationGroup

5 Use cases

5.1 General

This subclause describes the use cases of interest when using a secure element to protect the security objects used by OPC UA. The following scenarios are considered:

  • Transition from a DeviceIdentity personality to DCA personality (5.2)

  • Provisioning of ApplicationInstance personality

  • Use of ApplicationInstance personality for application authentication (5.5)

  • Management of ApplicationInstance Certificates and TrustLists

  • Factory reset / decommissioning

  • The analysis for the provisioning of personalities is based on the scenarios described in OPC 10000-21 The processes described in OPC 10000-21 provide the most comprehensive coverage of SecureElement usage. Scenarios for using SecureElements in combination with e.g., , can be easily derived from the information given in this document.

5.2 Device onboarding

Transition from a DeviceIdentity personality to DCA personality.

5.2.1 Preconditions

The device onboarding scenarios described in 5.2 makes the following assumptions:

  • At least one DeviceIdentity Personality (4.3.3) is present and managed by GTA API that can be used for the onboarding process (5.2.2).

  • This is the initial enrolment for the DCA, i.e., the DCA client does not yet have a TrustList

  • The registrar has access to a Ticket that identifies the device (https://reference.opcfoundation.org/Onboarding/v105/docs/3.1.19)

  • Key generation takes place on device, i.e. the private key is not provided by the Registrar.

For illustration the figures and explanations in sections 5.2.3.1 and 5.2.3.2 assume that the profile used for the DCA Personality is org.opcfoundation.ECC-nistp521 and substitutes examples values where values are to be supplied by the DCA:

urn:manufacturer.com:2024-10:myproduct:SN51235 for the ProductInstanceUri

urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=EccNistP256 for the base personality name of the DCA Identity Personality

urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup for the personality name of the DCA Trustlist Personality

For simplification all personalities are assumed to be created with initial access for access control (cf. ISO/IEC TS 30168 ED 1, 5.6.5.1). Refer to 7.1 for further information on access control.

5.2.2 Selection of DeviceIdentity for onboarding

The first step in the onboarding process is the selection of identities that the DCA offers to the Registrar.

There are different options available to enable the DCA to discover the available GTA API DeviceIdentity personalities (4.3.3).

Start from a well-known vendor defined personality name. This is the most straight forward approach. Figure 7 illustrates the interaction of DCA with GTA API. A vendor may also provide a list of personality names that can be provided to the Registrar.

Start from a well-known vendor defined identifier. Multiple DeviceIdentity personalities can be associated with the same identifier, e.g., to support different profiles. Figure 8 illustrates the interaction of DCA with GTA API. It is possible that multiple personalities are eligible for onboarding and are offered to the Registrar.

Start from a well-known vendor defined application name. Multiple personalities can be assigned the same application name. Figure 9 illustrates the interaction of DCA with GTA API. It is possible that multiple personalities are eligible for onboarding and are offered to the registrar.

Search for a personality flagged with the dedicated attribute type org.opcfoundation.product_instance_uri. Figure 10 illustrates the interaction of DCA with GTA API. It is possible that multiple personalities are eligible for onboarding and are offered to the Registrar.

The device vendor should advise the implementor of the DCA which options apply for a specific device.

Figure 7 – Discover DeviceIdentity personality using personality name
Figure 8 – Discover DeviceIdentity personality using identifier value
Figure 9 – Discover DeviceIdentity personality using application name

Annex A.1.1 provides a code example for the search and discovery of personalities by the application name.

Figure 10 – Discover DeviceIdentity personality using attribute type org.opcfoundation.product_instance_uri
Annex A.1.2 provides a code example for the search and discovery of personalities using attribute type org.opcfoundation.product_instance_uri.
The call to gta_context_open() at the end of each sequence is representative for any further operations the DCA intends to do with the selected personality, e.g., retrieval of the Device Identity Certificate that may be stored as part of the DeviceIdentity personality as shown in Figure 11.
Figure 11 – Get DeviceIdentity Certificate

Annex A.2 gives an example for the retrieval of personality attributes.

5.2.3 Provisioning of DCA’s Application Instance (Certificate)

This section shows how interaction with GTA API on the local endpoint maps into the overall onboarding process. During the course of the onboarding process a new personality for the DCA is created. The following operations are of interest with respect to the trust anchor:

Generate a new public/private key pair

Sign the proof-of-possession

Optional: Store end-entity certificate chain as part of the personality

Store the list of trusted certificates belonging to the DCA personality

The examples in this section use the ECC profile org.opcfoundation.ECC-nistP256 (6.1). They can be easily adapted to RSA by simply exchanging the profile name.
5.2.3.1 Pull Management

Figure 12 illustrates the use of TrustAnchor capabilities integrated in the Pull Management process (See OPC 10000-21).

Figure 12 – Onboarding of Device Configuration Application (Pull Management)

The process starts from selecting a DeviceIdentity(s) that are eligible for onboarding (see 5.2.2). The DCA client needs to maintain a mapping between DeviceIdentity certificates and the corresponding Device Identity personality.

The DCA client proposes all available DeviceIdentity to the Registrar which replies with the selected DeviceIdentity certificate.

The DCA client uses the selected DeviceIdentity to create a secure channel to the Registrar. Create SecureChannel involves the computation of a digital signature (gta_authenticate_data_detached()). Further details for establishing a secure channel are explained in 5.5. Since the DCA client did not yet store any trusted certificates there is no authentication of the Registrar.
The DCA client creates a new identifier for the DCA and creates a new DCA Identity Personality for that identifier (gta_identifier_assign(), gta_personality_create()). The identifier value and personality name are set according to 4.3.2.1 and 4.3.4.
After creation of the DCA Identity personality the DCA prepares to file a certificate signing request (CSR) for its own DCA Certificate (cf. OPC 10000-6 6.2, Table 45; ). Upfront the device specific information that should be included in the CSR is setup (gta_context_set_attribute()). Finally the proof-of-possession is computed and the completed CSR is returned to the DCA client (gta_pesonality_enroll()) and forwarded to the Registrar.

After the Registrar has processed the certificate signing request it provides the DCA Certificate and the DCA TrustList, i.e., the list of certificates that the DCA shall regard as trustworthy for future communications with OPC UA infrastructure services (e.g., Registrar., Certificate Manager)

Storage of the DCA Certificate within the trust anchor is optional as the certificate is protected by the issuer’s signature.

The integrity of the DCA TrustList shall be protected by the TrustAnchor. The DCA creates a dedicated DCA TrustList personality using the local data protection profile ch.iec.30168.basic.local_data_integrity_only. Storage of the TrustList objects is left to the application. The integrity of the TrustList objects is protected using a seal computed with gta_authenticate_data_detached(). The returned integrity protection seal is to be stored along-side the respective TrustList object by the application.
5.2.3.2 Push Management

Figure 13 illustrates the use of TrustAnchor capabilities integrated in the Push Management process (See OPC 10000-21).

Figure 13 – Onboarding of Device Configuration Application (Push Management)

In response to a GetEndpoints request received from the registrar the DCA server compiles a list of DeviceIdentity(s) that are eligible for onboarding (see 5.2.2). The DCA server needs to maintain a mapping between DeviceIdentity certificates and the corresponding DeviceIdentity personality. The list of EndpointDescriptions created from the available DeviceIdentity certificates is returned to the Registar.

The Registrar selects one DeviceIdentity and starts a create SecureChannel Request. Details for establishing a SecureChannel are explained in 5.5. The DeviceIdentity selected by the Registrar is indicated by the ReceiverCertificateThumbprint contained in the security header (See OPC 10000-6).

The subsequent actions of the DCA server towards the GTA API correspond to Pull Management.

The sequence following on CreateSigningRequest (Push) corresponds to the sequence used to prepare StartSigningRequest (Pull).

The sequence following on UpdateCertificate (Push) corresponds to the sequence following the response to StartSigningRequest (Pull)

The sequence following on UpdateTrustList (Push) corresponds to the sequence following the response to GetTrustList (Pull)

5.3 Update of DCA’s Application Instance (Certificate)

Figure 14 illustrates the update of the DCA Personality Set using PullManagement. The DCA Personality Set is assumed to be the result of the process described in 5.2.3.1.

As long as GTA API does not offer a functionality for in-place update of an existing personality (for example, &ix=1) the update process needs to create a new personality (for example, &ix=2) and removes the outdated personality (&ix=1) once the process has completed successfully.

Figure 14 – Update of Device Configuration Application (Pull Management)

As a precondition for all subsequent information exchanges between the DCA Client and the Certificate Manager, the DCA Client creates a secure channel to the Registrar using the existing DCA Identity Personality (4.3.4) named urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=EccNistP256&ix=1. Details on how to establish a secure channel using an existing personality are described in 5.5.

As the existing personality (&ix=1) is required until the update finishes successfully the DCA application creates a new personality named urn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=EccNistP256&ix=2 to accept the updated security objects. After receiving the new DCA Certificate, the old DCA Identity Personality is removed (gta_personality_remove()).
As in the initial onboarding process gta_personality_authenticate_data_detached() is used to compute integrity protection seals for the updated TrustList Objects.

Update of the DCA Identity Personality and TrustList can be performed in independent processes.

Update of the DCA Personality Set using Push Management works accordingly. The interactions between DCA application and GTA API are not affected by using either Push or Pull Management.

5.4 Provisioning of Application Instance

Figure 15 illustrates the use of TrustAnchor capabilities integrated in the Pull Management process for provisioning of Application Instance (cf. OPC 10000-21 7.2, Figure 5; https://reference.opcfoundation.org/Onboarding/v105/docs/7.2).

  • Establish OPC UA Secure Channel DCA – Registrar/GDS. Details on how to establish a secure channel using an existing personality are described in 5.5.

  • Create personality for Application Instance

	Generate private key (gta_personality_create())
	Sign proof-of-possession on CSR (gta_personality_enroll())
	Write end-entity certificate (gta_personality_add_attribute())
	Protect TrustList for Application PKI domain (gta_authenticate_data_detached())
Figure 15 – Provisioning of Application Instance (Pull Management)

Provisioning of an Application Instance using Push Management works accordingly. The interactions between DCA application and GTA API are not affected by using either Push or Pull Management.

5.5 Use of Application Instance personality to establish a secure channel

  • An overview of the sequence to establish a secure channel is given in OPC 10000-6.

Establishing a secure channel can be supported by the following TrustAnchor capabilities:

  • Computation of asymmetric cryptographic operations using private keys. Long-term private keys, i.e., private keys corresponding to an application certificate, can effectively be protected by TrustAnchor capabilities. OPC UA Secure Conversation uses these keys for authentication (ECC and RSA) and key transport (RSA only).

  • Protecting the trusted certificates used to verify the remote party.

5.5.1 Elliptic Curve Profiles

  • OPC 10000-6 describes the secure channel handshake and key negotiation for ECC.

  • Figure 16 – shows the security transformation required on OpenSecureChannel Request and OpenSecureChannel Response involving ECC operations with the persistent EC private key. The basic cryptographic operation used is the computation of an EC signature.

Annex B.1 shows an example for an OpenSecureChannel Request using ECC-nistP256 for further reference.

  • For ECC profiles the key agreement of the symmetric key to be used to protect the secure channel completely relies on ephemeral keys. These ephemeral keys need to be authenticated by a digital signature produced by the respective identity personalities. The signature generation process is sensitive and should rely on functions of the TrustAnchor. However, any computations relying on the ephemeral keys is expected to be done in software and does not rely on functionality offered by the TrustAnchor.

  • Figure 17 illustrates how the related TrustAnchor functions fit into the process to establish a secure channel based on an ECC SecurityPolicy at the client side.

Figure 17 – Establish Secure Channel (ECC, Client View)

The personality to be used for establishing the secure channel is determined from the exchange of GetEndpoints Request/Response. The example assumes that the client’s identity personality is named urn:manufacturer.com:2024-10:myproduct:myclient_appid?cg=DefaultApplicationGroup&ct=EccNistP256&ix=1.

As a first step the client must verify the identity of the server claimed by means of the server certificate send within GetEndpoints Response. This requires certificate path validation against the configured TrustList. The integrity of the TrustList information is protected and shall be verified before relying on it. Integrity verification is done using the respective TrustList personality urn:manufacturer.com:2024-10:myproduct:myclient_appid?cg=DefaultApplicationGroup and profile ch.iec.30168.basic.local_data_integrity_only. The client calls gta_verify_data_detached() to check the correctness of the integrity protection seal stored alongside the TrustList. Whether verification of the TrustList is performed once every time a new secure channel is established, at regular intervals, or only once per device power-cycle depends on the desired security level and is left to the application.

If the identity of the server is found to be valid the client starts to build the OpenSecureChannel Request.

Optionally, the client certificate can be retrieved from the identity personality using gta_personality_get_attribute().
Construction of the OpenSecureChannel Request involves the computation of a digital signature using the identity personality representing the client. The client calls gta_authenticate_data_detached() to calculate the required signature transformation ◯Figure 16 S as shown in Figure 16.
Figure 18 – Establish Secure Channel (ECC, Server View)
  • Figure 18 illustrates how the related TrustAnchor functions fit into the process to establish a secure channel based on an ECC SecurityPolicy at the server side.

The server selects the personality to be used for establishing the secure channel. The example assumes that the server’s identity personality is named urn:manufacturer.com:2024-10:myproduct:myserver_appid?cg=DefaultApplicationGroup&ct=EccNistP256&ix=1. Optionally, the server certificate can be retrieved from the identity personality using gta_personality_get_attribute().
After receiving the OpenSecureChannel Request the server must verify the identity of the client claimed by means of the client certificate provided by the OpenSecureChannel Request. This requires certificate path validation against the configured TrustList. The integrity of the TrustList information is protected and shall be verified before relying on it. Integrity verification is done using the respective TrustList personality urn:manufacturer.com:2024-10:myproduct:myserver_appid?cg=DefaultApplicationGroup and profile ch.iec.30168.basic.local_data_integrity_only. The server calls gta_verify_data_detached() to check the correctness of the integrity protection seal stored alongside the TrustList. Whether verification of the TrustList is performed once every time a new secure channel is established, at regular intervals, or only once per device power-cycle depends on the desired security level and is left to the application.

If the identity of the client is found to be valid the client starts to build the OpenSecureChannel Response.

Construction of the OpenSecureChannel Response involves the computation of a digital signature using the identity personality representing the server. The server calls gta_authenticate_data_detached() to calculate the required signature transformation ◯Figure 16 S as shown in Figure 16.

5.5.2 RSA Profiles

  • OPC 10000-6 6.7 (https://reference.opcfoundation.org/Core/Part6/v105/docs/6.7) describes the secure channel handshake and key negotiation used with RSA.

  • Figure 19 shows the security transformation required on OpenSecureChannel Request and OpenSecureChannel Response involving RSA operations with the persistent RSA private key. The basic cryptographic operations used are the computation of an RSA signature and the decryption of an RSA ciphertext used to exchange a secret between OPC client and OPC server.

Annex B.2 shows an example for an OpenSecureChannel Request using Aes256-Sha256-RsaPss for further reference.

  • Figure 20 illustrates how the related TrustAnchor functions fit into the process to establish a secure channel based on an RSA SecurityPolicy at the client side.

Figure 20 – Establish Secure Channel (RSA, Client View)

The personality to be used for establishing the secure channel is determined from the exchange of GetEndpoints Request/Response. The example assumes that the client’s identity personality is named urn:manufacturer.com:2024-10:myproduct:myclient_appid?cg=DefaultApplicationGroup&ct=Rsa2048&ix=1.

As a first step the client must verify the identity of the server claimed by means of the server certificate send within GetEndpoints Response. This requires certificate path validation against the configured TrustList. The integrity of the TrustList information is protected and shall be verified before relying on it. Integrity verification is done using the respective TrustList personality urn:manufacturer.com:2024-10:myproduct:myclient_appid?cg=DefaultApplicationGroup and profile ch.iec.30168.basic.local_data_integrity_only. The client calls gta_verify_data_detached() to check the correctness of the integrity protection seal stored alongside the TrustList. Whether verification of the TrustList is performed once every time a new secure channel is established, at regular intervals, or only once per device power-cycle depends on the desired security level and is left to the application.

If the identity of the server is found to be valid the client starts to build the OpenSecureChannel Request.

Optionally, the client certificate can be retrieved from the identity personality using gta_personality_get_attribute().
Construction of the OpenSecureChannel Request involves the computation of a digital signature using the identity personality representing the client. The client calls gta_authenticate_data_detached() to calculate the required signature transformation ◯Figure 16 S as shown in Figure 19. Note that the required encryption operation uses the server’s public key and does not involve TrustAnchor functionality.
After sending the OpenSecureChannel Request the client receives the OpenSecureChannel response from the server. The client needs to extract the serverNonce from the encrypted part of the OpenSecureChannel Response. The client uses gta_unseal_data() to compute the decryption operation involving the client’s identity personality (Figure 19, ◯Figure 16 X).
Figure 21 – Establish Secure Channel (RSA, Server View)
  • Figure 21 illustrates how the related TrustAnchor functions fit into the process to establish a secure channel based on an RSA SecurityPolicy at the server side.

The server selects the personality to be used for establishing the secure channel. The example assumes that the server’s identity personality is named urn:manufacturer.com:2024-10:myproduct:myserver_appid?cg=DefaultApplicationGroup&ct=Rsa2048&ix=1. Optionally, the server certificate can be retrieved from the identity personality using gta_personality_get_attribute().
After receiving the OpenSecureChannel Request the server must verify the identity of the client claimed by means of the client certificate provided by the OpenSecureChannel Request. This requires certificate path validation against the configured TrustList. The integrity of the TrustList information is protected and shall be verified before relying on it. Integrity verification is done using the respective TrustList personality urn:manufacturer.com:2024-10:myproduct:myserver_appid?cg=DefaultApplicationGroup and profile ch.iec.30168.basic.local_data_integrity_only. The server calls gta_verify_data_detached() to check the correctness of the integrity protection seal stored alongside the TrustList. Whether verification of the TrustList is performed once every time a new secure channel is established, at regular intervals, or only once per device power-cycle depends on the desired security level and is left to the application.
If the identity of the server is found to be valid the server needs to extract the clientNonce from the encrypted part of the OpenSecureChannel Request. The server uses gta_unseal_data() to compute the decryption operation involving the server’s identity personality (Figure 19, ◯Figure 16 X).
Construction of the OpenSecureChannel Response involves the computation of a digital signature using the identity personality representing the server. The server calls gta_authenticate_data_detached() to calculate the required signature transformation ◯Figure 16 S as shown in Figure 19.

5.6 CreateSession and ActivateSession

  • CreateSession and ActivateSession are used to establish Sessions based on the UserIdentity.

CreateSession and ActivateSession can be supported by the following TrustAnchor capabilities:

  • Computation of asymmetric cryptographic operations using private keys. Long-term private keys, i.e., private keys corresponding to an application certificate, can effectively be protected by TrustAnchor capabilities. CreateSession and ActivateSession use these keys to authenticate the identity of the client resp. server identity.

  • Protecting the UserIdentityToken (RSA only)

  • Note that authentication of the actual user using X.509 credentials is not in scope of this document. X.509 user credentials are supposed to be user specific and will typically not be persisted on the device.

5.6.1 Elliptic Curve Profiles

The interactions between Client and GTA API in the sequence shown in Figure 22 for CreateSession and ActivateSession are similar to the process to establish a secure channel shown in Figure 17. The two trust anchor functions used are gta_verify_data_detached() to validate the integrity seal on the TrustList and gta_authenticate_data_detached() to compute the authentication proof of the client.
Figure 22 – CreateSession, ActivateSession (ECC, Client View)
Likewise, the interactions between Server and GTA API in the sequence shown in Figure 23 for CreateSession and ActivateSession are similar to the process to establish a secure channel shown in Figure 18. The two trust anchor functions used are gta_verify_data_detached() to validate the integrity seal on the TrustList and gta_authenticate_data_detached() to compute the authentication proof of the server.
Figure 23 – CreateSession, ActivateSession (ECC, Server View)

Note that for ECC SecurityPolicies the protection of the UserIdentityToken is achieved using symmetric encryption with keys derived from the ECCDH handshake. Thus, the protection of the UserIdentityToken is done in software and does not require functionality provided by the trust anchor.

5.6.2 RSA Profiles

The interactions between Client and GTA API in the sequence shown in Figure 24 for CreateSession and ActivateSession are similar to the process to establish a SecureChannel shown in Figure 20. The two trust anchor functions used are gta_verify_data_detached() to validate the integrity seal on the TrustList and gta_authenticate_data_detached() to compute the authentication proof of the client.
Figure 24 – CreateSession, ActivateSession (RSA, Client View)
Likewise, the interactions between Server and GTA API in the sequence shown in Figure 25 for CreateSession and ActivateSession are similar to the process to establish a secure channel shown in Figure 21. The three trust anchor functions used are gta_verify_data_detached() to validate the integrity seal on the TrustList, gta_authenticate_data_detached() to compute the authentication proof of the server, and (conditionally) gta_unseal_data() to decrypt the UserIdentityToken provided by the Client. The protection of the UserIdentityToken only applies for UserNameIdentityToken and IssuedIdentityToken.

In contrary to the ECC SecurityPolicy described in 5.6.1, with RSA SecurityPolicies, the client used the servers public RSA key to encrypt the UserIdentityToken. Therefore, the server needs to use its private key to decrypt the UserIdentityToken. The private key is protected by the trust anchor.

Figure 25 – CreateSession, ActivateSession (RSA, Server View)

5.7 Rollback of device to “pre-onboarding” state

GTA API offers functionality to restore the state of a device TrustAnchor to a previous state. This can be useful to reset a device trust anchor to the device state as shipped by the manufacturer or to any subsequent restore point created before putting additional personalities on the device’s trust anchor. Potential applications in the context of OPC UA are either to reset the device trust anchor to the state before onboarding or to the state directly after onboarding the DCA Application Instance.

The mechanism to use device states are described in ISO/IEC TS 30168. The respective functions are gta_devicestate_transition() to create a restore point and gta_devicestate_recede() to return to a previous restore point.

6 GTA API Profiles for OPC UA

6.1 ECC-nistP256

6.1.1 GTA API Creation Profile org.opcfoundation.ECC-nistP256

The profile org.opcfoundation.ECC-nistP256 supports creation of a personality using gta_personality_create(). 
Table 1 – GTA API Creation Profile org.opcfoundation.ECC-nistP256
PropertyDescription
Security MechanismMechanism details as specified in SecurityPolicy [ECC-B] – ECC-nistP256
FingerprintingImplementation dependent
Attribute type ch.iec.30168.identifier (attribute name ch.iec.30168.identifier_value; cardinality 1)
The identifier value that is assigned to the personality at the time of its creation (cf. IEC TS 30168 6.6.10.4.13).
ch.iec.30168.trustlist.certificate.self.x509 (cardinality 0..1)
X.509 end entity certificate
org.opcfoundation.product_instance_uri (cardinality 0..1)
ProductInstanceUri represented by the personality. This attribute shall be present for personalities which are eligible identities to be used in the OPC UA onboarding process. This attribute should occur at most once. The attribute name shall be set to “ProductInstanceUri”.
Usage Infoorg.opcfoundation.ECC-nistP256

6.1.2 GTA API Enrollment Profile org.opcfoundation.ECC-nistP256

Table 2 – GTA API Enrollment Profile org.opcfoundation.ECC-nistP256
PropertyDescription
Profile Dependenciesorg.opcfoundation.ECC-nistP256 for creation
Enrollment Attributes org.opcfoundation.csr.subject (optional)
CertificateRequestInfo.subject (according to IETF RFC 2986) in ASN.1 DER coding (binary).
org.opcfoundation.csr.subjectAltName (optional)
CertificateRequestInfo.subjectAltName GeneralNames structure to appear as subjectAltName inside an extensionRequest (IETF RFC 2985, IETF RFC 2986). The value shall be specified as ASN.1 DER encoded GeneralNames structure according to IETF RFC 5280.
Enrollment Artifact

PKCS#10 according to RFC 2986 in ASN.1 DER coding (binary).

CertificateRequestInfo.subjectPKInfo contains the information on the personality’s EC public key. CertificationRequest.signatureAlgorithm and CertificationRequest.signature are providing the proof-of-possession calculated with the personality’s EC private key.
CertificateRequestInfo.subject is provided via gta_context_set_attribute().

The subject alternative name is set

	according to the context attribute type org.opcfoundation.csr.subjectAltName,or
	in case  org.opcfoundation.csr.subjectAltName is not set, the value is set according to the identifier that relates to the personality (personality attribute type ch.iec.30168.identifier) if the identifier type is org.opcfoundation.application_instance_urior

the function fails if none of the information described above is available.

6.1.3 GTA API Usage Profile org.opcfoundation.ECC-nistP256

Table 3 – GTA API Usage Profile org.opcfoundation.ECC-nistP256
PropertyDescription
Profile Dependenciesorg.opcfoundation.ECC-nistP256 for creation and enrolment
gta_personality_get_attribute()
ch.iec.30168.identifier ch.iec.30168.trustlist.certificate.self.x509 org.opcfoundation.product_instance_uri
gta_personality_add_attribute()
ch.iec.30168.trustlist.certificate.self.x509 org.opcfoundation.product_instance_uri
gta_personality_remove_attribute()
ch.iec.30168.trustlist.certificate.self.x509 org.opcfoundation.product_instance_uri
gta_authenticate_data_detached()

Signs data and returns a signature artifact depending on the mechanism of the used personality.

Mechanism details as specified in SecurityPolicy [ECC-B] – ECC-nistP256 (http://opcfoundation.org/UA/SecurityPolicy#ECC_nistP256)

Usage Attributesn/a
Usage Artifact

Binary

tbd.

6.2 Aes256-Sha256-RsaPss

6.2.1 GTA API Creation Profile org.opcfoundation.Aes256-Sha256-RsaPss

The profile org.opcfoundation.Aes256-Sha256-RsaPss supports creation of a personality using gta_personality_create(). 
Table 4 – GTA API Creation Profile org.opcfoundation.Aes256-Sha256-RsaPss
PropertyDescription
Security Mechanism

Mechanism details as specified in SecurityPolicy Aes256-Sha256-RsaPss

The expected key length is of 4096

FingerprintingToDo
Attribute type ch.iec.30168.identifier (attribute name ch.iec.30168.identifier_value; cardinality 1)
The identifier value that is assigned to the personality at the time of its creation (cf. IEC TS 30168 6.6.10.4.13).
ch.iec.30168.trustlist.certificate.self.x509
X.509 end entity certificate
org.opcfoundation.product_instance_uri
ProductInstanceUri represented by the personality. This attribute shall be present for personalities which are eligible identities to be used in the OPC UA onboarding process. This attribute should occur at most once per personality. The attribute name shall be set to “ProductInstanceUri”.
Usage Infoorg.opcfoundation.Aes256-Sha256-RsaPss

6.2.2 GTA API Enrollment Profile org.opcfoundation.Aes256-Sha256-RsaPss

Table 5 – GTA API Enrollment Profile org.opcfoundation.Aes256-Sha256-RsaPss
PropertyDescription
Profile Dependenciesorg.opcfoundation.Aes256-Sha256-RsaPss for creation
Enrollment Attributescf. Table 2
Enrollment Artifactcf. Table 2

6.2.3 GTA API Usage Profile org.opcfoundation.Aes256-Sha256-RsaPss

Table 6 – GTA API Usage Profile org.opcfoundation.Aes256-Sha256-RsaPss
PropertyDescription
Profile Dependenciesorg.opcfoundation.Aes256-Sha256-RsaPss for creation and enrolment
gta_personality_get_attribute()
ch.iec.30168.identifier ch.iec.30168.trustlist.certificate.self.x509 org.opcfoundation.product_instance_uri
gta_personality_add_attribute()
ch.iec.30168.trustlist.certificate.self.x509
gta_personality_remove_attribute()
ch.iec.30168.trustlist.certificate.self.x509
gta_authenticate_data_detached()

Signs data and returns a signature artifact depending on the mechanism of the used personality.

Mechanism details as specified in SecurityPolicy Aes256-Sha256-RsaPss (http://opcfoundation.org/UA/SecurityPolicy#Aes256-Sha256-RsaPss)
gta_unseal_data()

Decryption for OpenSecureChannel

Mechanism details as specified in SecurityPolicy Aes256-Sha256-RsaPss (http://opcfoundation.org/UA/SecurityPolicy#Aes256-Sha256-RsaPss)

Usage Attributesn/a
Usage Artifact

Binary

tbd.

7 Use case extensions

7.1 Access control

Usage of cryptographic objects needs to be protected. For example, application A must not be allowed to use cryptographic objects owned by application B to avoid that application B is able to act on behalf of application A (impersonation).

For OPC UA using GTA API ECC profiles, the following access control mechanisms offered by GTA API apply:

Usage: Protect access to private keys used with gta_authenticate_data_detached()
Admin: Protect against the unauthorized modification of trust lists managed with gta_personality_add_trusted_attribute().

The level of access protection required depends on individual device and applications. Table 7 gives an overview of the authorization options defined in ISO/IEC TS 30168.

Table 7 – Authorization options defined in ISO/IEC TS 30168
Authorization OptionAcquisitionTrust Model
Initial AccessAutomatic

Runtime system including applications is fully trusted. Trust in runtime system can be established by means of, e.g., secure boot.

Special protection provided by the SE applies for offline attacks (if the device is powered off)

Basic Access Tokens and Token Issuing TokensVia trusted system service (e.g., privileged OS service)Trust towards some core services of the runtime system. Trust towards these core services can be established by means of, e.g., CRTM, measured boot. Application access to SE resources can be limited/isolated on personality level.
Personality Derived Access TokensInteraction with (remote) 3rd partyPrivileged use of SE resources requires successful interaction with a trusted 3rd party, e.g., local user, remote attestation. This involves an additional personality used to interact with the 3rd party.

7.1.1 Initial Access

There are no OPC UA specifics needed to support the initial access authorization option. It is up to the specific GTA API implementation on a specific platform to provide means that support initial access regardless of the applications that make use of the GTA API.

7.1.2 Basic Access Tokens

The basic access token and token issuing token authorization option is based upon one or more trusted core services of the runtime system. In OPC UA environments where device onboarding according to OPC 10000-21 is possible, the DCA can be used as such a privileged process to acquire a token issuing token (see ISO/IEC TS 30168). After the DCA, when being called during powerup, has been provided with the token issuing token, basic access tokens may be distributed to the applications managed by the DCA. The DCA is suitable for this task since:

  1. The DCA has an overview on all OPC UA applications on the device.

  2. The DCA can be used to manage all personality objects and assign appropriate access conditions while creating respectively administrating the respective personalities.

After the applications had been provided with basic access tokens, they can use them to become authorized for using or managing the personalities in question. Figure 26 shows corresponding GTA API calls during different boot stages.

The following stages, as shown in Figure 26, are executed for the use of basic access tokens:

During the provisioning of Application Instance Personality Set(s), an access policy is set before creating personalities. When personalities are created, corresponding access policy handles are used with gta_personality_create().

During device boot stage 0, it is just assumed that the initial access condition is met.

During device boot stage 1, the DCA, as privileged application, issues a gta_access_token_get_issuing() call to acquire its token_issuing_token. Using the latter, it can call gta_access_token_get_basic() for specific personalities and access control usage. As a result, it is provided with corresponding basic access tokens.

The basic access tokens may then be distributed to applications known to the DCA and configured as authorized to use or manage certain personalities.

Applications need to provide the basic access tokens by using the gta_context_auth_set_access_token() call before respective calls that require authorization.

7.1.3 Personality Derived Access Tokens

The use of personality derived access tokens, especially in the context of OPC UA onboarding and certificate management, is not considered in the current version of this document.

Annex A – Implementation Examples

A.1 Selection of personalities

A.1.1 Enumerating all personalities by application

The example below enumerates all personalities with application “IDevID”. This can be useful to select personalities usable for onboarding (cf. 5.2.2, Figure 9).

gta_instance_handle_t h_inst;
gta_context_handle_t h_ctx = GTA_HANDLE_INVALID;
gta_errinfo_t errinfo;

bool b_loop_pers = true;
gta_enum_handle_t h_enum_pers = GTA_HANDLE_ENUM_FIRST;

while (b_loop_pers) {
    char pers_name[STR_LEN_MAX];
    myio_obufstream_t ostream_pers_name = { 0 };

    myio_open_obufstream(&ostream_pers_name, pers_name,
                         sizeof(pers_name), &errinfo);

    if (gta_personality_enumerate_application(h_inst,
            "IDevID", h_enum_pers, GTA_PERSONALITY_ENUM_ALL,
            (gtaio_ostream_t *)&o_pers_name, &errinfo)) {
        
             /* 
              * do something with personality pers_name 
              */            

        }
        else {
            b_loop_pers = false;
        }
        myio_close_obufstream(&ostream_pers_name, &errinfo);
    }
}

A.1.2 Discover DeviceIdentity personality using attribute org.opcfoundation.product_instance_uri

The example below enumerates all personalities and checks for the attribute org.opcfoundation.product_instance_uri

bool b_loop = true;
char identifier_type_buffer[200];
char identifier_value_buffer[200];
myio_obufstream_t ostream_identifier_type = { 0 };
myio_obufstream_t ostream_identifier_value = { 0 };
gta_enum_handle_t h_enum = GTA_HANDLE_ENUM_FIRST;

gta_context_handle_t h_ctx = GTA_HANDLE_INVALID;
bool exit_loops = false;
char selected_personality[100];

/* enumerate all identifiers */
while (b_loop && !exit_loops) {
    myio_open_obufstream(&ostream_identifier_type,
                         identifier_type_buffer,
                         sizeof(identifier_type_buffer),
                         &errinfo);
    myio_open_obufstream(&ostream_identifier_value,
                         identifier_value_buffer,
                         sizeof(identifier_value_buffer),
                         &errinfo);
    b_ret = gta_identifier_enumerate(
                h_inst,
                &h_enum,
                (gtaio_ostream_t *)&ostream_identifier_type,
                (gtaio_ostream_t *)&ostream_identifier_value,
                &errinfo);
    myio_close_obufstream(&ostream_identifier_type, &errinfo);
    myio_close_obufstream(&ostream_identifier_value, &errinfo);

    if (true == b_ret) {
        bool b_inner_loop = true;
        char personality_name_buffer[200];
        myio_obufstream_t ostream_personality_name = { 0 };
        gta_enum_handle_t h_enum_inner_loop = GTA_HANDLE_ENUM_FIRST;

        /* enumerate all personalities belonging to identifier */
        while (b_inner_loop && !exit_loops) {
            myio_open_obufstream(&ostream_personality_name,
                                 personality_name_buffer, 
                                 sizeof(personality_name_buffer),
                                 &errinfo);
            b_ret = gta_personality_enumerate(
                        h_inst,
                        identifier_value_buffer,
                        &h_enum_inner_loop,
                        GTA_PERSONALITY_ENUM_ALL,
                        (gtaio_ostream_t *)&ostream_personality_name,
                        &errinfo);
            myio_close_obufstream(&ostream_personality_name, &errinfo);

            if (true == b_ret) {
                bool b_innermost_loop = true;
                char attribute_type_buffer[200];
                char attribute_value_buffer[200];
                myio_obufstream_t ostream_attribute_type = { 0 };
                myio_obufstream_t ostream_attribute_value = { 0 };
                gta_enum_handle_t h_enum_innermost_loop
                    = GTA_HANDLE_ENUM_FIRST;
 
 
 
                /* enumerate all attributes belonging to personality */
                while (b_innermost_loop && !exit_loops) {
                    myio_open_obufstream(
                        &ostream_attribute_type,
                        attribute_type_buffer,
                        sizeof(attribute_type_buffer),
                        &errinfo);
                    myio_open_obufstream(
                        &ostream_attribute_value,
                        attribute_value_buffer,
                        sizeof(attribute_value_buffer),
                        &errinfo);
                    b_ret = gta_personality_attributes_enumerate(
                         h_inst,
                         personality_name_buffer,
                         &h_enum_innermost_loop,
                         (gtaio_ostream_t *)&ostream_attribute_type,
                         (gtaio_ostream_t *)&ostream_attribute_value,
                         &errinfo);
                    myio_close_obufstream(&ostream_attribute_type,
                                          &errinfo);
                    myio_close_obufstream(&ostream_attribute_value,
                                          &errinfo);
                    if (true == b_ret) {
                        if (0 == strcmp(
                            "org.opcfoundation.product_instance_uri",
                            attribute_type_buffer)) {
                            exit_loops = true;
                            strcpy(selected_personality,
                                   personality_name_buffer);
                        }
                    }
                    else {
                        b_innermost_loop = false;
                    }
                } 
             }
             else {
                 errinfo = 0;
                 b_inner_loop = false;
             }
         }
    }
    else {
        errinfo = 0;
        b_loop = false;
    }
}

/*
 * do something with selected personality
 */

A.2 Examination of personality attributes

The example below searches all attributes of a personality given by its name pers_name for an X.509 DeviceIdentity certificate.

bool b_loop_attr = true;
gta_enum_handle_t h_enum_attr = GTA_HANDLE_ENUM_FIRST;

while (b_loop_attr) {
    char attr_name[STR_LEN_MAX];
    char attr_type[STR_LEN_MAX];
    myio_obufstream_t ostream_attr_name = { 0 };
    myio_obufstream_t ostream_attr_type = { 0 };

    myio_open_obufstream(&ostream_attr_name, attr_name,
        sizeof(attr_name), &errinfo);
    myio_open_obufstream(&ostream_attr_type, attr_type,
        sizeof(attr_type), &errinfo);

    if (gta_personality_attributes_enumerate(h_inst,
         pers_name,
         h_enum_attr,
         (gtaio_ostream_t *)&ostream_attr_name,
         (gtaio_ostream_t *)&ostream_attr_type,
         &errinfo)) {

        /* Get the attribute holding the
           DeviceIdentity Certificate */
        
        if (0 == strncmp(attr_type, 
                   "ch.iec.30168.trustlist.certificate.self.x509",
                   STR_LEN_MAX)) {
            h_ctx = gta_context_open(h_inst,
                        pers_name,
                        "org.opcfoundation.ECC-nistP256",
                        &errinfo);

            /* get application certificate */
            char devid_cert[CERT_SIZE_MAX];
            myio_obufstream_t ostream_devid_cert = { 0 };
        
            myio_open_obufstream(&ostream_devid_cert,
                 devid_cert, sizeof(devid_cert), &errinfo);

            gta_personality_get_attribute(h_ctx,
                attr_name, (gtaio_ostream_t *)&ostream_devid_cert,
                &errinfo);

             /* ... make use of this DeviceIdentity Cerficate 
                (e.g., add it to a list) ... */
            
             gta_context_close(h_ctx, &errinfo);             
        }
    }
    else {
        b_loop_attr = false;
    }
    myio_close_obufstream(&ostream_attr_name, &errinfo);
    myio_close_obufstream(&ostream_attr_type, &errinfo);
}
Device onboarding for org.opcfoundation.ECC-nistP256

The example code below illustrates the use of GTA API to implement the scenario outlined in section 5.2.3.1, Figure 12.

The following assumptions apply:

Identifier used for the DCA Personality Set isurn:manufacturer.com:2024-10:myproduct:SN51235
Name used for the DCA Identity Personality isurn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup&ct=EccNistP256&ix=1
Name used for the DCA TrustList Personality isurn:manufacturer.com:2024-10:myproduct:SN51235?cg=DefaultApplicationGroup
Note that the example can be easily adjusted for any other profile by just switching to another profile (e.g., org.opcfoundation.Aes256-Sha256-RsaPss) and adjusting the identifier and personality names as desired.
gta_errinfo_t errinfo = 0;

char identifier_value[]
    = "urn:manufacturer.com:2024-10:myproduct:SN51235";
char personality_name[] 
    = "urn:manufacturer.com:2024-10:myproduct:SN51235?"
      "cg=DefaultApplicationGroup&ct=EccNistP256&ix=1";
char identity_profile[]
    = "org.opcfoundation.ECC-nistP256";
char application[] = "DCA Identity";
char trustlist_personality_name[]
    = "urn:manufacturer.com:2024-10:myproduct:SN51235?"
      "cg=DefaultApplicationGroup";
char trustlist_application[] = "DCA TrustList";
char trustlist_profile[]
    = "ch.iec.30168.basic.local_data_integrity_only";

/* Assign identifier */
gta_identifier_assign(
    h_inst,
    "org.opcfoundation.application_instance_uri",
    identifier_value,
    &errinfo);

/* Create DCA Identity Personality */
gta_access_policy_handle_t h_auth_use = GTA_HANDLE_INVALID;
h_auth_use = gta_access_policy_simple(
    h_inst,
    GTA_ACCESS_DESCRIPTOR_TYPE_INITIAL,
    &errinfo);
gta_access_policy_handle_t h_auth_use = GTA_HANDLE_INVALID;
h_auth_admin = gta_access_policy_simple(
    h_inst,
    GTA_ACCESS_DESCRIPTOR_TYPE_INITIAL,
    &errinfo);

struct gta_protection_properties_t protection_props = {0};

gta_personality_create(
    h_inst,
    identifier_value,
    personality_name,
    application,
    identity_profile,
    h_auth_use,
    h_auth_admin,
    protection_props,
    &errinfo);

/* Generate CSR */
gta_context_handle_t h_ctx = GTA_HANDLE_INVALID;
h_ctx = gta_context_open(
    h_inst,
    personality_name,
    "com.github.generic-trust-anchor-api.basic.enroll",
    &errinfo);

/* Set context attribute org.opcfoundation.csr.subject */
const char subject_der[] = {…};
size_t subject_der_len = …;
myio_ibufstream_t istream_subject = { 0 };
myio_open_ibufstream(
    &istream_subject,
    subject_der, subject_der_len,
    &errinfo);
gta_context_set_attribute(
    h_ctx,
    "org.opcfoundation.csr.subject",
    (gtaio_istream_t*)&istream_subject,
    &errinfo);
myio_close_ibufstream(&istream_subject, &errinfo);

/* Set context attribute org.opcfoundation.csr.subjectAltName */
const char subject_alt_name_der[] = {…};
size_t subject_alt_name_der_len = …;
myio_ibufstream_t istream_subject_alt_name = { 0 };
myio_open_ibufstream(
    &istream_subject_alt_name,
    subject_alt_name_der, subject_alt_name_der_len,
    &errinfo);
gta_context_set_attribute(
    h_ctx,
    "org.opcfoundation.csr.subjectAltName",
    (gtaio_istream_t*)&istream_subject_alt_name,
    &errinfo);
myio_close_ibufstream(&istream_subject_alt_name, &errinfo);

char csr_buffer[CSR_SIZE];
myio_obufstream_t ostream_csr = { 0 };
myio_open_obufstream(
    &ostream_csr,
    csr_buffer, sizeof(csr_buffer),
    &errinfo);
gta_personality_enroll(
    h_ctx,
    (gtaio_ostream_t*)&ostream_csr,
    &errinfo);
myio_close_obufstream(&ostream_csr, &errinfo);

/* Send CSR and receive certificate */
char cert_buffer[] = {…};
size_t cert_len = …;

/* Store DCA certificate (optional) */
myio_ibufstream_t istream_cert = { 0 };
myio_open_ibufstream(
    &istream_cert,
    cert_buffer, cert_len,
    &errinfo);
gta_personality_add_attribute(
    h_ctx,
    "ch.iec.30168.trustlist.certificate.self.x509",
    "DCA certificate",
    (gtaio_istream_t*)&istream_cert,
    &errinfo);
myio_close_ibufstream(&istream_cert, &errinfo);

gta_context_close(h_ctx, &errinfo);

/* Receive TrustList */
char trustlist_buffer[] = {…};
size_t trustlist_len = …;

/* Create DCA TrustList Personality */
gta_personality_create(
    h_inst,
    identifier_value,
    trustlist_personality_name,
    trustlist_application,
    trustlist_profile,
    h_auth_use,
    h_auth_admin,
    protection_props,
    &errinfo);

/* Protect DCA TrustList objects */
gta_context_handle_t h_ctx_seal = GTA_HANDLE_INVALID;
h_ctx_seal = gta_context_open(
    h_inst,
    trustlist_personality_name,
    trustlist_profile,
    &errinfo);

myio_ibufstream_t istream_trustlist = { 0 };
myio_open_ibufstream(
    &istream_trustlist,
    trustlist_buffer, trustlist_len,
    &errinfo);
#define INTEGRITY_PROTECTION_SEAL_LENGTH 32
char seal_buffer[INTEGRITY_PROTECTION_SEAL_LENGTH];
myio_obufstream_t ostream_seal = { 0 };
myio_open_obufstream(
    &ostream_seal,
    seal_buffer, sizeof(seal_buffer),
    &errinfo);
gta_authenticate_data_detached(
    h_ctx_seal,
    (gtaio_istream_t*)&istream_trustlist,
    (gtaio_ostream_t*)&ostream_seal,
    &errinfo);
myio_close_ibufstream(&istream_trustlist, &errinfo);
myio_close_obufstream(&ostream_seal, &errinfo);

gta_context_close(h_ctx_seal, &errinfo);

Using org.opcfoundation.Aes256-Sha256-RsaPss to create a OpenSecureChannel Response

The example code below illustrates the use of GTA API to implement the scenario outlined in section 5.5.2, Figure 21. Note that functionality expected to be provided by the application is not elaborated but only addressed in comments. Error handling is omitted for the sake of clarity of the workflow.

The following pre-conditions apply:

  • OPC UA application installed on device

  • The OPC UA application has been successfully onboarded (cf. 5.4)

	The OPC UA security policy used in OpenSecureChannel Response is  Aes256-Sha256-RsaPss
	The GTA API profile used in the example is org.opcfoundation.Aes256-Sha256-RsaPss
	The name of the attribute used to store the Application Instance Certificate is my_server
	The GTA API personality name used in the example is urn:manufacturer.com:2024-10:myproduct:myserver_appid?cg=DefaultApplicationGroup&ct=Rsa2048&ix=1
gta_errinfo_t errinfo = 0;

char personality_name[] 
    = "urn:manufacturer.com:2024-10:myproduct:myserver_appid?"
      "cg=DefaultApplicationGroup&ct=Rsa2048&ix=1";
char profile[]
    = "org.opcfoundation.Aes256-Sha256-RsaPss";
char certificate_name = "my_server";
char trustlist_personality_name[]
    = "urn:manufacturer.com:2024-10:myproduct:myserver_appid?"
      "cg=DefaultApplicationGroup;
char trustlist_profile[]
    = "ch.iec.30168.basic.local_data_integrity_only";

gta_context_handle_t h_ctx = GTA_HANDLE_INVALID;
h_ctx = gta_context_open(
    h_inst,
    personality_name,
    profile,
    &errinfo);	

/* Get server certificate from personality attribute (optional) */

char cert_buffer[CERT_SIZE];
myio_obufstream_t ostream_cert = { 0 };
gta_personality_get_attribute(
    h_ctx,
    certificate_name,
    (gtaio_ostream_t*)&ostream_cert,
    &errinfo);
myio_close_obufstream(&ostream_cert, &errinfo);

/* Prepare OpenSecureChannel Response */

gta_context_handle_t h_ctx_seal = GTA_HANDLE_INVALID;
h_ctx_seal = gta_context_open(
    h_inst,
    trustlist_personality_name,
    trustlist_profile,
    &errinfo);

char trustlist_buffer[] = {…};
size_t trustlist_len = …;
myio_ibufstream_t istream_trustlist = { 0 };
myio_open_ibufstream(
    &istream_trustlist,
    trustlist_buffer, trustlist_len,
    &errinfo);
char seal_buffer[] = {…};
size_t seal_len = …;
myio_ibufstream_t istream_seal = { 0 };
myio_open_ibufstream(
    &istream_seal,
    seal_buffer, seal_len,
    &errinfo);
if (!gta_verify_data_detached(
    h_ctx_seal,
    (gtaio_istream_t*)&istream_trustlist,
    (gtaio_istream_t*)&istream_seal,
    &errinfo)) {
    /* fail – TrustList has been tampered with */
}
myio_close_ibufstream(&istream_trustlist, &errinfo);
myio_close_ibufstream(&istream_seal, &errinfo);

gta_context_close(h_ctx_seal, &errinfo);

char encrypted_requestdata_buffer[] = {…};
size_t encrypted_requestdata_len = …;
myio_ibufstream_t istream_encrypted_requestdata = { 0 };
myio_open_ibufstream(
    &istream_encrypted_requestdata,
    encrypted_requestdata_buffer, encrypted_requestdata_len,
    &errinfo);
#define REQUESTDATA_SIZE 
char decrypted_requestdata_buffer[REQUESTDATA_SIZE];
myio_obufstream_t ostream_decrypted_requestdata = { 0 };
myio_open_obufstream(
    &ostream_decrypted_requestdata,
    decrypted_requestdata_buffer, sizeof(decrypted_requestdata_buffer),
    &errinfo);
gta_unseal_data(
    h_ctx,
    (gtaio_istream_t*)&istream_encrypted_requestdata,
    (gtaio_ostream_t*)&ostream_decrypted_requestdata,
    &errinfo);
myio_close_ibufstream(&istream_encrypted_requestdata, &errinfo);
myio_close_obufstream(&ostream_decrypted_requestdata, &errinfo);

char tbs_responsedata_buffer[] = {…};
size_t tbs_responsedata_len = …;
myio_ibufstream_t istream_tbs_responsedata = { 0 };
myio_open_ibufstream(
    &istream_tbs_responsedata,
    tbs_responsedata_buffer, tbs_responsedata_len,
    &errinfo);
#define SIGNATURE_SIZE 
char signature_buffer[SIGNATURE_SIZE];
myio_obufstream_t ostream_signature = { 0 };
myio_open_obufstream(
    &ostream_signature,
    signature_buffer, sizeof(signature_buffer),
    &errinfo);
gta_authenticate_data_detached(
    h_ctx,
    (gtaio_istream_t*)&istream_tbs_responsedata,
    (gtaio_ostream_t*)&ostream_signature,
    &errinfo);
myio_close_ibufstream(&istream_tbs_responsedata, &errinfo);
myio_close_obufstream(&ostream_signature, &errinfo);

gta_context_close(h_ctx, &errinfo);



Annex B – Example Messages

B.1 OpenSecureChannel Request example message (ECC-nistP256)

To be signedMessageHeaderMessageType 4f 50 4e
IsFinal 46
MessageSize 16 03 00 00
SecureChannelId 00 00 00 00
SecurityHeaderSecurityPolicyUri 37 00 00 00 68 74 74 70 3a 2f 2f 6f 70 63 66 6f 75 6e 64 61 74 69 6f 6e 2e 6f 72 67 2f 55 41 2f 53 65 63 75 72 69 74 79 50 6f 6c 69 63 79 23 45 43 43 5f 6e 69 73 74 50 32 35 36
SenderCertificate f6 01 00 00 30 82 01 f2 … 494 bytes skipped … 86 f3 20 fb
ReceiverCertificate
Thumbprint
14 00 00 00 cd d2 e6 82 92 1b b3 9b 5c 8e 07 f8 5d 74 b6 1b d1 a3 f4 6b
SequenceHeaderSequenceNumber 01 00 00 00
RequestId 05 00 00 00
OPNRequestRequestHeader 01 00 be 01 00 00 92 18 41 c8 57 f2 db 01 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SecurityMode 03 00 00 00
ClientNonce
(ECDHE public key)
40 00 00 00 9d 5c 32 2f 37 b4 8c 29 16 ae 10 f5 e1 cd ba 09 70 48 5d 2b 6d 26 10 22 92 22 32 7c 55 db 63 c6 9a 00 6a ac 90 d0 55 07 16 c3 68 fe 5e 8b e8 cb 83 59 a3 c6 41 58 81 69 1b f2 cc c4 35 7f 57 0e
RequestedLifetime c0 27 09 00
Signature 9b a3 ea f1 40 1c 80 69 8f c6 0a 8c ed fd b8 ff c0 e3 b9 28 0e 55 8a 54 09 ba 29 de 71 80 17 b9 e9 f7 30 9b 65 36 9b a3 c8 ae ac 00 b2 87 f7 be d9 90 0f 4b 49 1d 81 e5 dc 91 a4 8a 16 70 d7 39

B.2 OpenSecureChannel Request example message (Aes256-Sha256-RsaPss)

To be signedMessageHeaderMessageType 4f 50 4e
IsFinal 46
MessageSize 78 06 00 00
SecureChannelId 00 00 00 00
SecurityHeaderSecurityPolicyUri 40 00 00 00 68 74 74 70 3a 2f 2f 6f 70 63 66 6f 75 6e 64 61 74 69 6f 6e 2e 6f 72 67 2f 55 41 2f 53 65 63 75 72 69 74 79 50 6f 6c 69 63 79 23 41 65 73 31 32 38 5f 53 68 61 32 35 36 5f 52 73 61 4f 61 65 70
SenderCertificate 0c 04 00 00 30 82 04 08 … 1032 bytes skipped … f7 e3 e5 1e
ReceiverCertificate
Thumbprint
14 00 00 00 fc 85 2b 0c a9 16 23 81 80 75 6f aa 74 73 36 be 6d d2 89 28
To be encryptedSequenceHeaderSequenceNumber 01 00 00 00
RequestId 05 00 00 00
OPNRequestRequestHeader 01 00 be 01 00 00 dc 47 cd 55 cf f4 db 01 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SecurityMode 03 00 00 00
ClientNonce 20 00 00 00 60 58 cb 4d 5c 34 92 a4 c3 dc ae d7 bd b2 4a 27 b9 0c 2b 5d d1 62 d3 1e 15 5d a7 7d 1a a9 3f 4f
RequestedLifetime c0 27 09 00
Padding 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e 4e
Signature 98 ad ec f4 dc ed 97 00 fe bd e2 28 e8 12 f8 1b f4 ea 2c db d7 71 fe 9c 8e 3b 77 99 b6 6c 00 3d fd 7b c2 e6 f4 1c a4 40 a2 5b cc f6 d2 c2 7e 14 04 82 6b 57 80 8e a9 3e 0f c1 5f af 2e 78 50 a6 24 79 b8 cf 95 b8 10 15 9c bc 46 07 77 67 42 1d 00 f3 5a 64 d7 0b 82 8b 08 7a 49 19 1c fa 0e fd 2d c1 fb b5 b9 38 20 9a ba 93 16 37 3a 79 e9 8e 8f 19 22 17 8c a7 e1 17 c8 d2 11 94 26 fa 2f 64 09 08 9b 8d 58 fc 6e c3 e4 f1 bc fe dc 45 59 e5 87 3f f3 c4 f1 56 2b 75 d2 fb 8e 7b e1 2e 37 1e a4 f9 15 c2 f5 f5 59 53 b6 10 d5 36 3a fe 38 9c 88 60 76 a2 d6 01 01 ba 18 a2 81 9d 33 99 a9 72 73 ab 64 f5 a3 e7 24 09 be cb cb df 7a f4 3f 5e 37 b7 a8 f9 32 e2 c2 5b eb f7 2e d1 81 45 95 51 85 b5 b6 04 7e 72 45 5b c5 f5 56 70 bc c7 e8 eb 32 65 57 c8 3e ff 7d b9 34 79 d7 23 b4 5a d1 62