Parcourir la source

Add tests and possibility to set key sizes in test

New tests that test for correct message structure and correct padding calculation.
Also, it is now possible to set key sizes and so forth in each test.
Defaults are provided by the setup functions.
Mark il y a 6 ans
Parent
commit
3d6ad6a0cb

+ 133 - 4
tests/check_securechannel.c

@@ -19,7 +19,15 @@
 
 #include "check.h"
 
-#define UA_BYTESTRING_STATIC(s) {sizeof(s)-1, (UA_Byte*)s}
+#define UA_BYTESTRING_STATIC(s) {sizeof(s)-1, (UA_Byte*)(s)}
+
+// Some default testing sizes. Can be overwritten in testing functions.
+#define DEFAULT_SYM_ENCRYPTION_BLOCK_SIZE 2
+#define DEFAULT_SYM_SIGNING_KEY_LENGTH 3
+#define DEFAULT_SYM_ENCRYPTION_KEY_LENGTH 5
+#define DEFAULT_ASYM_REMOTE_SIGNATURE_SIZE 7
+#define DEFAULT_ASYM_LOCAL_SIGNATURE_SIZE 11
+#define DEFAULT_ASYM_REMOTE_PLAINTEXT_BLOCKSIZE 256
 
 UA_SecureChannel testChannel;
 UA_ByteString dummyCertificate = UA_BYTESTRING_STATIC("DUMMY CERTIFICATE DUMMY CERTIFICATE DUMMY CERTIFICATE");
@@ -28,11 +36,12 @@ UA_Connection testingConnection;
 UA_ByteString sentData;
 
 
-funcs_called fCalled;
+static funcs_called fCalled;
+static key_sizes keySizes;
 
 static void
 setup_secureChannel(void) {
-    TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled);
+    TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled, &keySizes);
     UA_SecureChannel_init(&testChannel, &dummyPolicy, &dummyCertificate);
 
     testingConnection = createDummyConnection(&sentData);
@@ -58,6 +67,27 @@ teardown_funcs_called(void) {
     memset(&fCalled, 0, sizeof(struct funcs_called));
 }
 
+static void
+setup_key_sizes(void) {
+    memset(&keySizes, 0, sizeof(struct key_sizes));
+
+    keySizes.sym_sig_keyLen = DEFAULT_SYM_SIGNING_KEY_LENGTH;
+    keySizes.sym_enc_blockSize = DEFAULT_SYM_ENCRYPTION_BLOCK_SIZE;
+    keySizes.sym_enc_keyLen = DEFAULT_SYM_ENCRYPTION_KEY_LENGTH;
+
+    keySizes.asym_lcl_sig_size = DEFAULT_ASYM_LOCAL_SIGNATURE_SIZE;
+    keySizes.asym_rmt_sig_size = DEFAULT_ASYM_REMOTE_SIGNATURE_SIZE;
+
+    keySizes.asym_rmt_ptext_blocksize = DEFAULT_ASYM_REMOTE_PLAINTEXT_BLOCKSIZE;
+    keySizes.asym_rmt_enc_key_size = 2048;
+    keySizes.asym_lcl_enc_key_size = 1024;
+}
+
+static void
+teardown_key_sizes(void) {
+    memset(&keySizes, 0, sizeof(struct key_sizes));
+}
+
 /*
 static void
 setup_dummyPolicy(void) {
@@ -71,7 +101,7 @@ teardown_dummyPolicy(void) {
 
 START_TEST(SecureChannel_initAndDelete)
     {
-        TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled);
+        TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled, &keySizes);
         UA_StatusCode retval;
 
         UA_SecureChannel channel;
@@ -322,6 +352,99 @@ START_TEST(SecureChannel_sendAsymmetricOPNMessage_sentDataIsValid)
         ck_assert_msg(memcmp(&sentResponse, &dummyResponse, sizeof(UA_OpenSecureChannelResponse)) == 0,
                       "Expected the sent response to be equal to the one supplied to the send function");
 
+        UA_Byte paddingByte = sentData.data[offset];
+        size_t paddingSize = (size_t) paddingByte;
+
+        for(size_t i = 0; i <= paddingSize; ++i) {
+            ck_assert_msg(sentData.data[offset + i] == paddingByte,
+                          "Expected padding byte %i to be %i but got value %i",
+                          i,
+                          paddingByte,
+                          sentData.data[offset + i]);
+        }
+
+        ck_assert_msg(sentData.data[offset + paddingSize + 1] == '*', "Expected first byte of signature");
+
+        UA_SecureConversationMessageHeader_deleteMembers(&header);
+        UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymSecurityHeader);
+        UA_SequenceHeader_deleteMembers(&sequenceHeader);
+        UA_OpenSecureChannelResponse_deleteMembers(&sentResponse);
+    }
+END_TEST
+
+START_TEST(Securechannel_sendAsymmetricOPNMessage_extraPaddingPresentWhenKeyLargerThan2048Bits)
+    {
+        keySizes.asym_rmt_enc_key_size = 4096;
+        keySizes.asym_rmt_ptext_blocksize = 4096;
+
+        UA_OpenSecureChannelResponse dummyResponse;
+        createDummyResponse(&dummyResponse);
+
+        testChannel.securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
+        UA_UInt32 requestId = UA_UInt32_random();
+
+        UA_StatusCode retval = UA_SecureChannel_sendAsymmetricOPNMessage(&testChannel,
+                                                                         requestId,
+                                                                         &dummyResponse,
+                                                                         &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]);
+        ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Expected function to succeed");
+
+        size_t offset = 0;
+        UA_SecureConversationMessageHeader header;
+        UA_SecureConversationMessageHeader_decodeBinary(&sentData, &offset, &header);
+
+        UA_AsymmetricAlgorithmSecurityHeader asymSecurityHeader;
+        UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(&sentData, &offset, &asymSecurityHeader);
+        ck_assert_msg(UA_ByteString_equal(&dummyCertificate, &asymSecurityHeader.senderCertificate),
+                      "Expected the certificate to be equal to the one used  by the secureChannel");
+        ck_assert_msg(UA_ByteString_equal(&testChannel.securityPolicy->policyUri,
+                                          &asymSecurityHeader.securityPolicyUri),
+                      "Expected securityPolicyUri to be equal to the one used by the secureChannel");
+        UA_ByteString thumbPrint = {20, testChannel.remoteCertificateThumbprint};
+        ck_assert_msg(UA_ByteString_equal(&thumbPrint,
+                                          &asymSecurityHeader.receiverCertificateThumbprint),
+                      "Expected receiverCertificateThumbprint to be equal to the one set in the secureChannel");
+
+        for(size_t i = offset; i < header.messageHeader.messageSize; ++i) {
+            sentData.data[i] = (UA_Byte) ((sentData.data[i] - 1) % (UA_BYTE_MAX + 1));
+        }
+
+        UA_SequenceHeader sequenceHeader;
+        UA_SequenceHeader_decodeBinary(&sentData, &offset, &sequenceHeader);
+        ck_assert_msg(sequenceHeader.requestId == requestId, "Expected requestId to be %i but was %i",
+                      requestId,
+                      sequenceHeader.requestId);
+
+        UA_NodeId original = UA_NODEID_NUMERIC(0, UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE].binaryEncodingId);
+        UA_NodeId requestTypeId;
+        UA_NodeId_decodeBinary(&sentData, &offset, &requestTypeId);
+        ck_assert_msg(UA_NodeId_equal(&original, &requestTypeId), "Expected nodeIds to be equal");
+
+        UA_OpenSecureChannelResponse sentResponse;
+        UA_OpenSecureChannelResponse_decodeBinary(&sentData, &offset, &sentResponse);
+
+        ck_assert_msg(memcmp(&sentResponse, &dummyResponse, sizeof(UA_OpenSecureChannelResponse)) == 0,
+                      "Expected the sent response to be equal to the one supplied to the send function");
+
+        UA_Byte paddingByte = sentData.data[offset];
+        UA_Byte extraPaddingByte = sentData.data[sentData.length - keySizes.asym_lcl_sig_size - 1];
+        size_t paddingSize = (size_t) paddingByte;
+        paddingSize |= extraPaddingByte << 8;
+
+        for(size_t i = 0; i <= paddingSize; ++i) {
+            ck_assert_msg(sentData.data[offset + i] == paddingByte,
+                          "Expected padding byte %i to be %i but got value %i",
+                          i,
+                          paddingByte,
+                          sentData.data[offset + i]);
+        }
+
+        ck_assert_msg(sentData.data[offset + paddingSize + 1] == extraPaddingByte, "Expected extra padding byte to be "
+            "%i but got %i",
+                      extraPaddingByte, sentData.data[offset + paddingSize + 1]);
+        ck_assert_msg(sentData.data[offset + paddingSize + 2] == '*', "Expected first byte 42 of signature but got %i",
+                      sentData.data[offset + paddingSize + 2]);
+
         UA_SecureConversationMessageHeader_deleteMembers(&header);
         UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymSecurityHeader);
         UA_SequenceHeader_deleteMembers(&sequenceHeader);
@@ -335,24 +458,28 @@ testSuite_SecureChannel(void) {
 
     TCase *tc_initAndDelete = tcase_create("Initialize and delete Securechannel");
     tcase_add_checked_fixture(tc_initAndDelete, setup_funcs_called, teardown_funcs_called);
+    tcase_add_checked_fixture(tc_initAndDelete, setup_key_sizes, teardown_key_sizes);
     tcase_add_test(tc_initAndDelete, SecureChannel_initAndDelete);
     tcase_add_test(tc_initAndDelete, SecureChannel_initAndDelete_invalidParameters);
     suite_add_tcase(s, tc_initAndDelete);
 
     TCase *tc_generateNewKeys = tcase_create("Test generateNewKeys function");
     tcase_add_checked_fixture(tc_generateNewKeys, setup_funcs_called, teardown_funcs_called);
+    tcase_add_checked_fixture(tc_generateNewKeys, setup_key_sizes, teardown_key_sizes);
     tcase_add_checked_fixture(tc_generateNewKeys, setup_secureChannel, teardown_secureChannel);
     tcase_add_test(tc_generateNewKeys, SecureChannel_generateNewKeys);
     suite_add_tcase(s, tc_generateNewKeys);
 
     TCase *tc_revolveTokens = tcase_create("Test revolveTokens function");
     tcase_add_checked_fixture(tc_revolveTokens, setup_funcs_called, teardown_funcs_called);
+    tcase_add_checked_fixture(tc_revolveTokens, setup_key_sizes, teardown_key_sizes);
     tcase_add_checked_fixture(tc_revolveTokens, setup_secureChannel, teardown_secureChannel);
     tcase_add_test(tc_revolveTokens, SecureChannel_revolveTokens);
     suite_add_tcase(s, tc_revolveTokens);
 
     TCase *tc_sendAsymmetricOPNMessage = tcase_create("Test sendAsymmetricOPNMessage function");
     tcase_add_checked_fixture(tc_sendAsymmetricOPNMessage, setup_funcs_called, teardown_funcs_called);
+    tcase_add_checked_fixture(tc_sendAsymmetricOPNMessage, setup_key_sizes, teardown_key_sizes);
     tcase_add_checked_fixture(tc_sendAsymmetricOPNMessage, setup_secureChannel, teardown_secureChannel);
     tcase_add_test(tc_sendAsymmetricOPNMessage, SecureChannel_sendAsymmetricOPNMessage_withoutConnection);
     tcase_add_test(tc_sendAsymmetricOPNMessage, SecureChannel_sendAsymmetricOPNMessage_invalidParameters);
@@ -361,6 +488,8 @@ testSuite_SecureChannel(void) {
     tcase_add_test(tc_sendAsymmetricOPNMessage, SecureChannel_sendAsymmetricOPNMessage_SecurityModeSign);
     tcase_add_test(tc_sendAsymmetricOPNMessage, SecureChannel_sendAsymmetricOPNMessage_SecurityModeSignAndEncrypt);
     tcase_add_test(tc_sendAsymmetricOPNMessage, SecureChannel_sendAsymmetricOPNMessage_sentDataIsValid);
+    tcase_add_test(tc_sendAsymmetricOPNMessage,
+                   Securechannel_sendAsymmetricOPNMessage_extraPaddingPresentWhenKeyLargerThan2048Bits);
     suite_add_tcase(s, tc_sendAsymmetricOPNMessage);
 
 

+ 37 - 34
tests/testing-plugins/testing_policy.c

@@ -11,15 +11,11 @@
 #include "testing_policy.h"
 #include "check.h"
 
+#ifndef __clang_analyzer__
 #define SET_CALLED(func) funcsCalled->func = true
 
-#define SYM_ENCRYPTION_BLOCK_SIZE 2
-#define SYM_SIGNING_KEY_LENGTH 3
-#define SYM_ENCRYPTION_KEY_LENGTH 5
-#define ASYM_REMOTE_SIGNATURE_SIZE 7
-#define ASYM_LOCAL_SIGNATURE_SIZE 11
-
-funcs_called *funcsCalled;
+static funcs_called *funcsCalled;
+static const key_sizes *keySizes;
 
 static UA_StatusCode
 verify_testing(const UA_SecurityPolicy *securityPolicy,
@@ -40,10 +36,12 @@ asym_sign_testing(const UA_SecurityPolicy *securityPolicy,
     ck_assert(message != NULL);
     ck_assert(signature != NULL);
 
-    ck_assert_msg(signature->length == ASYM_LOCAL_SIGNATURE_SIZE,
+    ck_assert_msg(signature->length == keySizes->asym_lcl_sig_size,
                   "Expected signature length to be %i but was %i",
-                  ASYM_LOCAL_SIGNATURE_SIZE,
+                  keySizes->asym_lcl_sig_size,
                   signature->length);
+
+    memset(signature->data, '*', signature->length);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -70,7 +68,7 @@ asym_getLocalSignatureSize_testing(const UA_SecurityPolicy *securityPolicy,
     ck_assert(securityPolicy != NULL);
     ck_assert(channelContext != NULL);
 
-    return ASYM_LOCAL_SIGNATURE_SIZE;
+    return keySizes->asym_lcl_sig_size;
 }
 
 static size_t
@@ -79,19 +77,19 @@ asym_getRemoteSignatureSize_testing(const UA_SecurityPolicy *securityPolicy,
     ck_assert(securityPolicy != NULL);
     ck_assert(channelContext != NULL);
 
-    return ASYM_REMOTE_SIGNATURE_SIZE;
+    return keySizes->asym_rmt_sig_size;
 }
 
 static size_t
 asym_getLocalEncryptionKeyLength_testing(const UA_SecurityPolicy *securityPolicy,
                                          const void *channelContext) {
-    return 0;
+    return keySizes->asym_lcl_enc_key_size;
 }
 
 static size_t
 asym_getRemoteEncryptionKeyLength_testing(const UA_SecurityPolicy *securityPolicy,
                                           const void *channelContext) {
-    return 0;
+    return keySizes->asym_rmt_enc_key_size;
 }
 
 static size_t
@@ -111,13 +109,13 @@ sym_getLocalEncryptionKeyLength_testing(const UA_SecurityPolicy *securityPolicy,
                                         const void *channelContext) {
     ck_assert(securityPolicy != NULL);
     ck_assert(channelContext != NULL);
-    return SYM_ENCRYPTION_KEY_LENGTH;
+    return keySizes->sym_enc_keyLen;
 }
 
 static size_t
 sym_getRemoteEncryptionKeyLength_testing(const UA_SecurityPolicy *securityPolicy,
                                          const void *channelContext) {
-    return SYM_ENCRYPTION_KEY_LENGTH;
+    return keySizes->sym_enc_keyLen;
 }
 
 static UA_StatusCode
@@ -142,8 +140,10 @@ asym_encrypt_testing(const UA_SecurityPolicy *securityPolicy,
 
     size_t blockSize = securityPolicy->channelModule.getRemoteAsymPlainTextBlockSize(securityPolicy);
     ck_assert_msg(data->length % blockSize == 0,
-                  "Expected the length of the data to be encrypted to be a multiple of the plaintext block size (%i)",
-                  blockSize);
+                  "Expected the length of the data to be encrypted to be a multiple of the plaintext block size (%i). "
+                      "Remainder was %i",
+                  blockSize,
+                  data->length % blockSize);
 
     for(size_t i = 0; i < data->length; ++i) {
         data->data[i] = (UA_Byte) ((data->data[i] + 1) % (UA_BYTE_MAX + 1));
@@ -186,11 +186,11 @@ generateKey_testing(const UA_SecurityPolicy *securityPolicy,
                     const UA_ByteString *secret,
                     const UA_ByteString *seed,
                     UA_ByteString *out) {
-    SET_CALLED(generateKey);
     ck_assert(securityPolicy != NULL);
     ck_assert(secret != NULL);
     ck_assert(seed != NULL);
     ck_assert(out != NULL);
+    SET_CALLED(generateKey);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -232,9 +232,9 @@ setLocalSymEncryptingKey_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_ENCRYPTION_KEY_LENGTH,
+    ck_assert_msg(val->length == keySizes->sym_enc_keyLen,
                   "Expected length to be %i but got %i",
-                  SYM_ENCRYPTION_KEY_LENGTH,
+                  keySizes->sym_enc_keyLen,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
@@ -246,9 +246,9 @@ setLocalSymSigningKey_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_SIGNING_KEY_LENGTH,
+    ck_assert_msg(val->length == keySizes->sym_sig_keyLen,
                   "Expected length to be %i but got %i",
-                  SYM_SIGNING_KEY_LENGTH,
+                  keySizes->sym_sig_keyLen,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
@@ -260,9 +260,9 @@ setLocalSymIv_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_ENCRYPTION_BLOCK_SIZE,
+    ck_assert_msg(val->length == keySizes->sym_enc_blockSize,
                   "Expected length to be %i but got %i",
-                  SYM_ENCRYPTION_BLOCK_SIZE,
+                  keySizes->sym_enc_blockSize,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
@@ -274,9 +274,9 @@ setRemoteSymEncryptingKey_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_ENCRYPTION_KEY_LENGTH,
+    ck_assert_msg(val->length == keySizes->sym_enc_keyLen,
                   "Expected length to be %i but got %i",
-                  SYM_ENCRYPTION_KEY_LENGTH,
+                  keySizes->sym_enc_keyLen,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
@@ -288,9 +288,9 @@ setRemoteSymSigningKey_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_SIGNING_KEY_LENGTH,
+    ck_assert_msg(val->length == keySizes->sym_sig_keyLen,
                   "Expected length to be %i but got %i",
-                  SYM_SIGNING_KEY_LENGTH,
+                  keySizes->sym_sig_keyLen,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
@@ -302,16 +302,16 @@ setRemoteSymIv_testing(void *channelContext,
     ck_assert(channelContext != NULL);
     ck_assert(val != NULL);
     ck_assert(val->data != NULL);
-    ck_assert_msg(val->length == SYM_ENCRYPTION_BLOCK_SIZE,
+    ck_assert_msg(val->length == keySizes->sym_enc_blockSize,
                   "Expected length to be %i but got %i",
-                  SYM_ENCRYPTION_BLOCK_SIZE,
+                  keySizes->sym_enc_blockSize,
                   val->length);
     return UA_STATUSCODE_GOOD;
 }
 
 static size_t
 getRemoteAsymPlainTextBlockSize_testing(const void *channelContext) {
-    return 5;
+    return keySizes->asym_rmt_ptext_blocksize;
 }
 
 static size_t
@@ -333,7 +333,8 @@ policy_deletemembers_testing(UA_SecurityPolicy *policy) {
 
 UA_StatusCode
 TestingPolicy(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
-              funcs_called *fCalled) {
+              funcs_called *fCalled, const key_sizes *kSizes) {
+    keySizes = kSizes;
     funcsCalled = fCalled;
     policy->policyContext = (void *) funcsCalled;
     policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Testing");
@@ -363,8 +364,8 @@ TestingPolicy(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
     policy->symmetricModule.cryptoModule.decrypt = decrypt_testing;
     policy->symmetricModule.cryptoModule.getLocalEncryptionKeyLength = sym_getLocalEncryptionKeyLength_testing;
     policy->symmetricModule.cryptoModule.getRemoteEncryptionKeyLength = sym_getRemoteEncryptionKeyLength_testing;
-    policy->symmetricModule.encryptionBlockSize = SYM_ENCRYPTION_BLOCK_SIZE;
-    policy->symmetricModule.signingKeyLength = SYM_SIGNING_KEY_LENGTH;
+    policy->symmetricModule.encryptionBlockSize = keySizes->sym_enc_blockSize;
+    policy->symmetricModule.signingKeyLength = keySizes->sym_sig_keyLen;
 
     policy->channelModule.newContext = newContext_testing;
     policy->channelModule.deleteContext = deleteContext_testing;
@@ -382,3 +383,5 @@ TestingPolicy(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
 
     return UA_STATUSCODE_GOOD;
 }
+
+#endif

+ 13 - 1
tests/testing-plugins/testing_policy.h

@@ -39,9 +39,21 @@ typedef struct funcs_called {
     bool setRemoteSymIv;
 } funcs_called;
 
+typedef struct key_sizes {
+    size_t sym_enc_blockSize;
+    size_t sym_sig_keyLen;
+    size_t sym_enc_keyLen;
+
+    size_t asym_rmt_sig_size;
+    size_t asym_lcl_sig_size;
+    size_t asym_rmt_ptext_blocksize;
+    size_t asym_rmt_enc_key_size;
+    size_t asym_lcl_enc_key_size;
+} key_sizes;
+
 UA_StatusCode UA_EXPORT
 TestingPolicy(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
-              funcs_called *fCalled);
+              funcs_called *fCalled, const key_sizes *kSizes);
 
 #ifdef __cplusplus
 }