SecurityPolicy Plugin API ========================= .. code-block:: c typedef struct { UA_String uri; /* Verifies the signature of the message using the provided keys in the * context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channelContext that contains the key to verify * the supplied message with. * @param message The message to which the signature is supposed to belong. * @param signature The signature of the message, that should be verified. */ UA_StatusCode (*verify)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *message, const UA_ByteString *signature); /* Signs the given message using this policys signing algorithm and the * provided keys in the context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channelContext that contains the key to sign * the supplied message with. * @param message The message to sign. * @param signature An output buffer to which the signature is written. The * buffer needs to be allocated by the caller. The necessary size can * be acquired with the signatureSize attribute of this module. */ UA_StatusCode (*sign)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *message, UA_ByteString *signature); /* Gets the signature size that depends on the local (private) key. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channelContext that contains the * certificate/key. * @return The size of the local signature. Returns 0 if no local * certificate was set. */ size_t (*getLocalSignatureSize)(const UA_SecurityPolicy *policy, const void *channelContext); /* Gets the signature size that depends on the remote (public) key. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The size of the remote signature. Returns 0 if no * remote certificate was set previousely. */ size_t (*getRemoteSignatureSize)(const UA_SecurityPolicy *policy, const void *channelContext); /* Gets the local signing key length. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The length of the signing key in bytes. Returns 0 if no length * can be found. */ size_t (*getLocalKeyLength)(const UA_SecurityPolicy *policy, const void *channelContext); /* Gets the local signing key length. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The length of the signing key in bytes. Returns 0 if no length * can be found. */ size_t (*getRemoteKeyLength)(const UA_SecurityPolicy *policy, const void *channelContext); } UA_SecurityPolicySignatureAlgorithm; typedef struct { UA_String uri; /* Encrypt the given data in place. For asymmetric encryption, the block * size for plaintext and cypher depend on the remote key (certificate). * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channelContext which contains information about * the keys to encrypt data. * @param data The data that is encrypted. The encrypted data will overwrite * the data that was supplied. */ UA_StatusCode (*encrypt)(const UA_SecurityPolicy *policy, void *channelContext, UA_ByteString *data); /* Decrypts the given ciphertext in place. For asymmetric encryption, the * block size for plaintext and cypher depend on the local private key. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channelContext which contains information about * the keys needed to decrypt the message. * @param data The data to decrypt. The decryption is done in place. */ UA_StatusCode (*decrypt)(const UA_SecurityPolicy *policy, void *channelContext, UA_ByteString *data); /* Returns the length of the key used to encrypt messages in bits. For * asymmetric encryption the key length is for the local private key. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The length of the local key. Returns 0 if no * key length is known. */ size_t (*getLocalKeyLength)(const UA_SecurityPolicy *policy, const void *channelContext); /* Returns the length of the key to encrypt messages in bits. Depends on the * key (certificate) from the remote side. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The length of the remote key. Returns 0 if no * key length is known. */ size_t (*getRemoteKeyLength)(const UA_SecurityPolicy *policy, const void *channelContext); /* Returns the size of encrypted blocks for sending. For asymmetric * encryption this depends on the remote key (certificate). For symmetric * encryption the local and remote encrypted block size are identical. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The size of encrypted blocks in bytes. Returns 0 if no key length * is known. */ size_t (*getRemoteBlockSize)(const UA_SecurityPolicy *policy, const void *channelContext); /* Returns the size of plaintext blocks for sending. For asymmetric * encryption this depends on the remote key (certificate). For symmetric * encryption the local and remote plaintext block size are identical. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to retrieve data from. * @return The size of plaintext blocks in bytes. Returns 0 if no key length * is known. */ size_t (*getRemotePlainTextBlockSize)(const UA_SecurityPolicy *policy, const void *channelContext); } UA_SecurityPolicyEncryptionAlgorithm; typedef enum { UA_SECURITYPOLICYTYPE_NONE = 0, UA_SECURITYPOLICYTYPE_RSA = 1, UA_SECURITYPOLICYTYPE_ECC = 2 } UA_SecurityPolicyType; struct UA_SecurityPolicy { void *policyContext; /* Context data */ const UA_Logger *logger; /* Logger to be used by the plugin */ UA_String policyUri; /* SecurityPolicyUri */ /* Value indicating the crypto strength of the policy, with zero for * deprecated or none */ UA_Byte securityLevel; /* For special handling of SecurityPolicies using ECC (Elliptic Curve * Cryptography) */ UA_SecurityPolicyType policyType; /* The local certificate is specific for each SecurityPolicy since it * depends on the used key length. */ UA_ByteString localCertificate; UA_NodeId certificateGroupId; UA_NodeId certificateTypeId; /* Function pointers grouped into modules */ UA_SecurityPolicySignatureAlgorithm asymSignatureAlgorithm; UA_SecurityPolicyEncryptionAlgorithm asymEncryptionAlgorithm; UA_SecurityPolicySignatureAlgorithm symSignatureAlgorithm; UA_SecurityPolicyEncryptionAlgorithm symEncryptionAlgorithm; UA_SecurityPolicySignatureAlgorithm certSignatureAlgorithm; /* Create a new channel context. The caller needs to call delete on the * received object to free allocated memory. Memory is only allocated if the * function succeeds so there is no need to manually free the memory pointed * to by *channelContext or to call delete in case of failure. * * @param policy The policy for which the channelContext is created. * @param remoteCertificate The remote certificate contains the remote * asymmetric key. The certificate will be verified and then stored * in the context so that its details may be accessed. * @param channelContext The initialized channelContext that is passed to * functions that work on a context. */ UA_StatusCode (*newChannelContext)(const UA_SecurityPolicy *policy, const UA_ByteString *remoteCertificate, void **channelContext); /* Deletes the the channel context. */ void (*deleteChannelContext)(const UA_SecurityPolicy *policy, void *channelContext); /* Sets the local encrypting key in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param key The local encrypting key to store in the context. */ UA_StatusCode (*setLocalSymEncryptingKey)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *key); /* Sets the local signing key in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param key The local signing key to store in the context. */ UA_StatusCode (*setLocalSymSigningKey)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *key); /* Sets the local initialization vector in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param iv The local initialization vector to store in the context. */ UA_StatusCode (*setLocalSymIv)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *iv); /* Sets the remote encrypting key in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param key The remote encrypting key to store in the context. */ UA_StatusCode (*setRemoteSymEncryptingKey)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *key); /* Sets the remote signing key in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param key The remote signing key to store in the context. */ UA_StatusCode (*setRemoteSymSigningKey)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *key); /* Sets the remote initialization vector in the supplied context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context to work on. * @param iv The remote initialization vector to store in the context. */ UA_StatusCode (*setRemoteSymIv)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *iv); /* Compares the supplied certificate with the remote certificate stored in * the channel context. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The channel context data that contains the * certificate to compare to. * @param certificate The certificate to compare to the one stored in the context. * @return If the certificates match UA_STATUSCODE_GOOD is returned. If they * don't match or an errror occurred an error code is returned. */ UA_StatusCode (*compareCertificate)(const UA_SecurityPolicy *policy, const void *channelContext, const UA_ByteString *certificate); /* Generate the keys for symmetric encryption. For information on what * parameters this function receives in what situation, refer to the OPC UA * specification Part 6, "Deriving keys". * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context of the SecureChannel * @param secret Usually from the nonce. See part 6. * @param seed Usually from the nonce. See part 6. * @param out An output to write the data to. The length defines the maximum * number of output bytes that are produced. */ UA_StatusCode (*generateKey)(const UA_SecurityPolicy *policy, void *channelContext, const UA_ByteString *secret, const UA_ByteString *seed, UA_ByteString *out); /* Random generator for generating nonces. * * @param policy The SecurityPolicy to which the callback belongs. * @param channelContext The context of the SecureChannel * @param out Pointer to a buffer to store the nonce in. Needs to be * allocated by the caller. The buffer is filled with random data. */ UA_StatusCode (*generateNonce)(const UA_SecurityPolicy *policy, void *channelContext, UA_ByteString *out); /* The length of the nonce used in the SecureChannel */ size_t nonceLength; /* Generates a thumbprint for the specified certificate. * * @param policy The policy that generates the thumbprint. * @param certificate The certificate to make a thumbprint of. * @param thumbprint an output buffer for the resulting thumbprint. */ UA_StatusCode (*makeCertThumbprint)(const UA_SecurityPolicy *policy, const UA_ByteString *certificate, UA_ByteString *thumbprint); /* Compares the supplied certificate with the certificate in the * SecurityPolicy context. * * @param policy The policy data that contains the certificate * to compare to. * @param thumbprint The certificate thumbprint to compare to the one stored * in the context. * @return If the thumbprints match UA_STATUSCODE_GOOD is returned. If they * don't match or an error occurred an error code is returned. */ UA_StatusCode (*compareCertThumbprint)(const UA_SecurityPolicy *policy, const UA_ByteString *thumbprint); /* Updates the ApplicationInstanceCertificate and the corresponding private * key at runtime. This overwrites the localCertificate member of the * SecurityPolicy structure and updates the context internally. */ UA_StatusCode (*updateCertificate)(UA_SecurityPolicy *policy, const UA_ByteString certificate, const UA_ByteString privateKey); /* Creates a PKCS #10 DER encoded certificate request signed with the * server's private key. * * @param policy The SecurityPolicy to work on. * @param subjectName The subject name to use in the Certificate Request. If * not specified the SubjectName from the current Certificate is * used. * @param nonce Additional entropy that the caller can provide. It shall be * at least 32 bytes long. * @param params A KeyVaue list that can be used for additional parameters * later. * @param csr Returns the created CSR. If the passed byte string is not * empty, nothing is created. * @param newPrivateKey Returns the private key if a new one needs to be * generated. Alternatively, an existing key can be provided, which * will be used as the CSR key in the security policy. This is * necessary if the CSR was created under a different security policy * and the current one only requires an update. */ UA_StatusCode (*createSigningRequest)(UA_SecurityPolicy *policy, const UA_String *subjectName, const UA_ByteString *nonce, const UA_KeyValueMap *params, UA_ByteString *csr, UA_ByteString *newPrivateKey); /* Deletes the dynamic content of the policy */ void (*clear)(UA_SecurityPolicy *policy); }; PubSub SecurityPolicy --------------------- For PubSub encryption, the message nonce is part of the (unencrypted) SecurityHeader. The nonce is required for the de- and encryption and has to be set in the channel context before de/encrypting. .. code-block:: c struct UA_PubSubSecurityPolicy; typedef struct UA_PubSubSecurityPolicy UA_PubSubSecurityPolicy; struct UA_PubSubSecurityPolicy { void *policyContext; const UA_Logger *logger; UA_String policyUri; /* The policy uri that identifies the implemented * algorithms */ /* Create the context for the WriterGroup / ReaderGroup. The keys and nonce * can be NULL here. Then they have to be set before the first encryption or * signing operation. */ UA_StatusCode (*newGroupContext)(UA_PubSubSecurityPolicy *policy, const UA_ByteString *signingKey, const UA_ByteString *encryptingKey, const UA_ByteString *keyNonce, void **gContext); /* Delete the WriterGroup SecurityPolicy context */ void (*deleteGroupContext)(UA_PubSubSecurityPolicy *policy, void *gContext); /* See UA_SecurityPolicy for the following method signatures */ UA_StatusCode (*verify)(const UA_PubSubSecurityPolicy *policy, void *gContext, const UA_ByteString *message, const UA_ByteString *signature); UA_StatusCode (*sign)(const UA_PubSubSecurityPolicy *policy, void *gContext, const UA_ByteString *message, UA_ByteString *signature); size_t (*getSignatureSize)(const UA_PubSubSecurityPolicy *policy, const void *gContext); size_t (*getSignatureKeyLength)(const UA_PubSubSecurityPolicy *policy, const void *gContext); size_t (*getEncryptionKeyLength)(const UA_PubSubSecurityPolicy *policy, const void *gContext); UA_StatusCode (*encrypt)(const UA_PubSubSecurityPolicy *policy, void *gContext, UA_ByteString *data); UA_StatusCode (*decrypt)(const UA_PubSubSecurityPolicy *policy, void *gContext, UA_ByteString *data); /* Set the keys and nonce for the WriterGroup. This is returned from the * GetSecurityKeys method of a Security Key Service (SKS). Otherwise, set * manually via out-of-band transmission of the keys. */ UA_StatusCode (*setSecurityKeys)(UA_PubSubSecurityPolicy *policy, void *gContext, const UA_ByteString *signingKey, const UA_ByteString *encryptingKey, const UA_ByteString *keyNonce); /* Generate the keys for symmetric encryption. * * @param policy The SecurityPolicy to which the callback belongs. * @param gContext The group context. * @param secret Usually from the nonce. See part 6. * @param seed Usually from the nonce. See part 6. * @param out An output to write the data to. The length defines the maximum * number of output bytes that are produced. */ UA_StatusCode (*generateKey)(UA_PubSubSecurityPolicy *policy, void *gContext, const UA_ByteString *secret, const UA_ByteString *seed, UA_ByteString *out); /* Random generator for generating nonces. * * @param policy The SecurityPolicy to which the callback belongs. * @param wgContext The context of the SecureChannel * @param out Pointer to a buffer to store the nonce in. Needs to be * allocated by the caller. The buffer is filled with random data. */ UA_StatusCode (*generateNonce)(UA_PubSubSecurityPolicy *policy, void *gContext, UA_ByteString *out); /* The length of the nonce used in the SecureChannel */ size_t nonceLength; /* The nonce is contained in the NetworkMessage SecurityHeader. Set before * each en-/decryption step. */ UA_StatusCode (*setMessageNonce)(UA_PubSubSecurityPolicy *policy, void *gContext, const UA_ByteString *nonce); /* Deletes the dynamic content of the policy */ void (*clear)(UA_PubSubSecurityPolicy *policy); };