Sfoglia il codice sorgente

Calculate the largest possible message body to fit the padding

Jonas Green 6 anni fa
parent
commit
f8c062c3be
1 ha cambiato i file con 27 aggiunte e 15 eliminazioni
  1. 27 15
      src/ua_securechannel.c

+ 27 - 15
src/ua_securechannel.c

@@ -576,7 +576,7 @@ setBufPos(UA_MessageContext *mc) {
     /* Forward the data pointer so that the payload is encoded after the
      * message header */
     mc->buf_pos = &mc->messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH];
-    mc->buf_end = &mc->messageBuffer.data[mc->messageBuffer.length-UA_SECURE_MESSAGE_HEADER_LENGTH-1];
+    mc->buf_end = &mc->messageBuffer.data[mc->messageBuffer.length];
 
     /* Reserve space for the message footer at the end of the chunk if the chunk
      * is signed and/or encrypted. The footer includes the fields PaddingSize,
@@ -584,21 +584,33 @@ setBufPos(UA_MessageContext *mc) {
      * if the chunk is encrypted. */
     if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
        channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
-        mc->buf_end -= securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm.
-            getLocalSignatureSize(securityPolicy, channel->channelContext);
-
-    /* The size of the padding depends on the amount of data that shall be sent
-     * and is unknown at this point. Reserve space for the PaddingSize byte,
-     * the maximum amount of Padding which equals the block size of the
-     * symmetric encryption algorithm and last 1 byte for the ExtraPaddingSize
-     * field that is present if the encryption key is larger than 2048 bits.
-     * The actual padding size is later calculated by the function
-     * calculatePaddingSym(). */
-    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
     {
-        size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.
-            getLocalBlockSize(securityPolicy, channel->channelContext );
-        mc->buf_end -= 1 + (UA_Byte)encryptionBlockSize + ((encryptionBlockSize >> 8)?1:0);
+        size_t signatureSize = securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm.
+            getLocalSignatureSize(securityPolicy, channel->channelContext);
+        mc->buf_end -= signatureSize;
+
+        /* The size of the padding depends on the amount of data that shall be sent
+         * and is unknown at this point. Reserve space for the PaddingSize byte,
+         * the maximum amount of Padding which equals the block size of the
+         * symmetric encryption algorithm and last 1 byte for the ExtraPaddingSize
+         * field that is present if the encryption key is larger than 2048 bits.
+         * The actual padding size is later calculated by the function
+         * calculatePaddingSym(). */
+        if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
+        {
+            /* PaddingSize and ExtraPaddingSize fields */
+            size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.
+                getLocalBlockSize(securityPolicy, channel->channelContext );
+            mc->buf_end -= 1 + (encryptionBlockSize>>8)?1:0;
+
+            /* Reduce the message body size with the remainder of the operation
+             * maxEncryptedDataSize modulo EncryptionBlockSize to get a whole
+             * number of blocks to encrypt later. Also reserve one byte for
+             * padding (1 <= paddingSize <= encryptionBlockSize).
+             */
+            size_t maxEncryptDataSize = mc->messageBuffer.length-UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH-UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH;
+            mc->buf_end -= (maxEncryptDataSize % encryptionBlockSize) + 1;
+        }
     }
 }