Pārlūkot izejas kodu

check return values in securechannel

Julius Pfrommer 6 gadi atpakaļ
vecāks
revīzija
8086a32714
3 mainītis faili ar 58 papildinājumiem un 30 dzēšanām
  1. 2 2
      include/ua_config.h.in
  2. 32 21
      include/ua_plugin_securitypolicy.h
  3. 24 7
      src/ua_securechannel.c

+ 2 - 2
include/ua_config.h.in

@@ -162,7 +162,7 @@ extern "C" {
 /**
  * Function attributes
  * ------------------- */
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 # define UA_FUNC_ATTR_MALLOC __attribute__((malloc))
 # define UA_FUNC_ATTR_PURE __attribute__ ((pure))
 # define UA_FUNC_ATTR_CONST __attribute__((const))
@@ -176,7 +176,7 @@ extern "C" {
 # define UA_FORMAT(X,Y)
 #endif
 
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 # define UA_DEPRECATED __attribute__((deprecated))
 #elif defined(_MSC_VER)
 # define UA_DEPRECATED __declspec(deprecated)

+ 32 - 21
include/ua_plugin_securitypolicy.h

@@ -29,9 +29,8 @@ typedef struct {
      * @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 *securityPolicy,
-                            const void *channelContext,
-                            const UA_ByteString *message,
-                            const UA_ByteString *signature);
+                            const void *channelContext, const UA_ByteString *message,
+                            const UA_ByteString *signature) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Signs the given message using this policys signing algorithm and the
      * provided keys in the context.
@@ -45,9 +44,8 @@ typedef struct {
      *                  necessary size can be acquired with the signatureSize
      *                  attribute of this module. */
     UA_StatusCode (*sign)(const UA_SecurityPolicy *securityPolicy,
-                          const void *channelContext,
-                          const UA_ByteString *message,
-                          UA_ByteString *signature);
+                          const void *channelContext, const UA_ByteString *message,
+                          UA_ByteString *signature) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Gets the signature size that depends on the local (private) key.
      *
@@ -79,7 +77,8 @@ typedef struct {
      *             the data that was supplied. */
     UA_StatusCode(*encrypt)(const UA_SecurityPolicy *securityPolicy,
                             const void *channelContext,
-                            UA_ByteString *data);
+                            UA_ByteString *data) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
+
     /* Decrypts the given ciphertext in place using an asymmetric algorithm and
      * key.
      *
@@ -89,7 +88,7 @@ typedef struct {
      * @param data the data to decrypt. The decryption is done in place. */
     UA_StatusCode(*decrypt)(const UA_SecurityPolicy *securityPolicy,
                             const void *channelContext,
-                            UA_ByteString *data);
+                            UA_ByteString *data) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Returns the length of the key used locally to encrypt messages in bits
      *
@@ -120,7 +119,8 @@ typedef struct {
      *                   asymmetricModule. */
     UA_StatusCode (*makeCertificateThumbprint)(const UA_SecurityPolicy *securityPolicy,
                                                const UA_ByteString *certificate,
-                                               UA_ByteString *thumbprint);
+                                               UA_ByteString *thumbprint)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Compares the supplied certificate with the certificate in the endpoit context.
      *
@@ -131,7 +131,8 @@ typedef struct {
      * @return if the thumbprints match UA_STATUSCODE_GOOD is returned. If they
      *         don't match or an error occured an error code is returned. */
     UA_StatusCode (*compareCertificateThumbprint)(const UA_SecurityPolicy *securityPolicy,
-                                                  const UA_ByteString *certificateThumbprint);
+                                                  const UA_ByteString *certificateThumbprint)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     UA_SecurityPolicyCryptoModule cryptoModule;
 } UA_SecurityPolicyAsymmetricModule;
@@ -149,8 +150,8 @@ typedef struct {
      *            number of output bytes that are produced. */
     UA_StatusCode (*generateKey)(const UA_SecurityPolicy *securityPolicy,
                                  const UA_ByteString *secret,
-                                 const UA_ByteString *seed,
-                                       UA_ByteString *out);
+                                 const UA_ByteString *seed, UA_ByteString *out)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
     /* Random generator for generating nonces.
      *
      * @param securityPolicy the securityPolicy this function is invoked on.
@@ -160,7 +161,8 @@ typedef struct {
      *            allocated by the caller. The buffer is filled with random
      *            data. */
     UA_StatusCode (*generateNonce)(const UA_SecurityPolicy *securityPolicy,
-                                   UA_ByteString *out);
+                                   UA_ByteString *out)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     UA_SecurityPolicyCryptoModule cryptoModule;
     size_t encryptionBlockSize;
@@ -186,7 +188,8 @@ typedef struct {
      *                       functions that work on a context. */
     UA_StatusCode (*newContext)(const UA_SecurityPolicy *securityPolicy,
                                 const UA_ByteString *remoteCertificate,
-                                void **channelContext);
+                                void **channelContext)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Deletes the the security context. */
     void (*deleteContext)(void *channelContext);
@@ -196,41 +199,48 @@ typedef struct {
      * @param channelContext the context to work on.
      * @param key the local encrypting key to store in the context. */
     UA_StatusCode (*setLocalSymEncryptingKey)(void *channelContext,
-                                              const UA_ByteString *key);
+                                              const UA_ByteString *key)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Sets the local signing key in the supplied context.
      *
      * @param channelContext the context to work on.
      * @param key the local signing key to store in the context. */
     UA_StatusCode (*setLocalSymSigningKey)(void *channelContext,
-                                           const UA_ByteString *key);
+                                           const UA_ByteString *key)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Sets the local initialization vector in the supplied context.
      *
      * @param channelContext the context to work on.
      * @param iv the local initialization vector to store in the context. */
     UA_StatusCode (*setLocalSymIv)(void *channelContext,
-                                   const UA_ByteString *iv);
+                                   const UA_ByteString *iv)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
+
     /* Sets the remote encrypting key in the supplied context.
      *
      * @param channelContext the context to work on.
      * @param key the remote encrypting key to store in the context. */
     UA_StatusCode (*setRemoteSymEncryptingKey)(void *channelContext,
-                                               const UA_ByteString *key);
+                                               const UA_ByteString *key)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Sets the remote signing key in the supplied context.
      *
      * @param channelContext the context to work on.
      * @param key the remote signing key to store in the context. */
     UA_StatusCode (*setRemoteSymSigningKey)(void *channelContext,
-                                            const UA_ByteString *key);
+                                            const UA_ByteString *key)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Sets the remote initialization vector in the supplied context.
      *
      * @param channelContext the context to work on.
      * @param iv the remote initialization vector to store in the context. */
     UA_StatusCode (*setRemoteSymIv)(void *channelContext,
-                                    const UA_ByteString *iv);
+                                    const UA_ByteString *iv)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Compares the supplied certificate with the certificate in the channel
      * context.
@@ -241,7 +251,8 @@ typedef struct {
      * @return if the certificates match UA_STATUSCODE_GOOD is returned. If they
      *         don't match or an errror occured an error code is returned. */
     UA_StatusCode (*compareCertificate)(const void *channelContext,
-                                        const UA_ByteString *certificate);
+                                        const UA_ByteString *certificate)
+        UA_FUNC_ATTR_WARN_UNUSED_RESULT;
 
     /* Gets the plaintext block size that depends on the remote public key.
      *

+ 24 - 7
src/ua_securechannel.c

@@ -126,14 +126,15 @@ UA_SecureChannel_generateNewKeys(UA_SecureChannel *const channel) {
     const UA_ByteString remoteIv = { symmetricModule->encryptionBlockSize,
                                     buffer.data + symmetricModule->signingKeyLength +
                                     encryptionKeyLength };
-    retval = channelModule->setRemoteSymSigningKey(channel->channelContext, &remoteSigningKey);
+    retval  = channelModule->setRemoteSymSigningKey(channel->channelContext, &remoteSigningKey);
     retval |= channelModule->setRemoteSymEncryptingKey(channel->channelContext, &remoteEncryptingKey);
     retval |= channelModule->setRemoteSymIv(channel->channelContext, &remoteIv);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
     /* Local keys */
-    symmetricModule->generateKey(securityPolicy, &channel->remoteNonce, &channel->localNonce, &buffer);
+    retval = symmetricModule->generateKey(securityPolicy, &channel->remoteNonce,
+                                          &channel->localNonce, &buffer);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     const UA_ByteString localSigningKey = { symmetricModule->signingKeyLength, buffer.data };
@@ -142,7 +143,7 @@ UA_SecureChannel_generateNewKeys(UA_SecureChannel *const channel) {
     const UA_ByteString localIv = { symmetricModule->encryptionBlockSize,
                                     buffer.data + symmetricModule->signingKeyLength +
                                     encryptionKeyLength };
-    retval = channelModule->setLocalSymSigningKey(channel->channelContext, &localSigningKey);
+    retval  = channelModule->setLocalSymSigningKey(channel->channelContext, &localSigningKey);
     retval |= channelModule->setLocalSymEncryptingKey(channel->channelContext, &localEncryptingKey);
     retval |= channelModule->setLocalSymIv(channel->channelContext, &localIv);
     return retval;
@@ -360,8 +361,12 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 r
         size_t sigsize = securityPolicy->asymmetricModule.cryptoModule.
             getLocalSignatureSize(securityPolicy, channel->channelContext);
         UA_ByteString signature = { sigsize, buf.data + pre_sig_length };
-        securityPolicy->asymmetricModule.cryptoModule.
+        retval = securityPolicy->asymmetricModule.cryptoModule.
             sign(securityPolicy, channel->channelContext, &dataToSign, &signature);
+        if(retval != UA_STATUSCODE_GOOD) {
+            connection->releaseSendBuffer(connection, &buf);
+            return retval;
+        }
     }
 
     /* Encrypt message if mode not none */
@@ -371,8 +376,12 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 r
             UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength;
         UA_ByteString dataToEncrypt = { total_length - unencrypted_length,
                                        &buf.data[unencrypted_length] };
-        securityPolicy->asymmetricModule.cryptoModule.
+        retval = securityPolicy->asymmetricModule.cryptoModule.
             encrypt(securityPolicy, channel->channelContext, &dataToEncrypt);
+        if(retval != UA_STATUSCODE_GOOD) {
+            connection->releaseSendBuffer(connection, &buf);
+            return retval;
+        }
     }
 
     /* Send the message, the buffer is freed in the network layer */
@@ -493,8 +502,12 @@ sendChunkSymmetric(UA_ChunkInfo* ci, UA_Byte **buf_pos, const UA_Byte **buf_end)
         signature.length = securityPolicy->symmetricModule.cryptoModule.
             getLocalSignatureSize(securityPolicy, channel->channelContext);
         signature.data = *buf_pos;
-        securityPolicy->symmetricModule.cryptoModule.
+        ci->errorCode = securityPolicy->symmetricModule.cryptoModule.
             sign(securityPolicy, channel->channelContext, &dataToSign, &signature);
+        if(ci->errorCode != UA_STATUSCODE_GOOD) {
+            connection->releaseSendBuffer(channel->connection, &ci->messageBuffer);
+            return ci->errorCode;
+        }
     }
 
     /* Encrypt message */
@@ -502,8 +515,12 @@ sendChunkSymmetric(UA_ChunkInfo* ci, UA_Byte **buf_pos, const UA_Byte **buf_end)
         UA_ByteString dataToEncrypt;
         dataToEncrypt.data = ci->messageBuffer.data + UA_SECUREMH_AND_SYMALGH_LENGTH;
         dataToEncrypt.length = total_length - UA_SECUREMH_AND_SYMALGH_LENGTH;
-        securityPolicy->symmetricModule.cryptoModule.
+        ci->errorCode = securityPolicy->symmetricModule.cryptoModule.
             encrypt(securityPolicy, channel->channelContext, &dataToEncrypt);
+        if(ci->errorCode != UA_STATUSCODE_GOOD) {
+            connection->releaseSendBuffer(channel->connection, &ci->messageBuffer);
+            return ci->errorCode;
+        }
     }
 
     /* Send the chunk, the buffer is freed in the network layer */