Browse Source

SecureChannel: Split into _init and _setSecurityPolicy

Julius Pfrommer 5 years ago
parent
commit
7e635abcda

+ 7 - 43
src/client/ua_client.c

@@ -37,8 +37,7 @@ UA_Client_init(UA_Client* client, UA_ClientConfig config) {
     memset(client, 0, sizeof(UA_Client));
     /* TODO: Select policy according to the endpoint */
     UA_SecurityPolicy_None(&client->securityPolicy, NULL, UA_BYTESTRING_NULL, config.logger);
-    client->channel.securityPolicy = &client->securityPolicy;
-    client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;
+    UA_SecureChannel_init(&client->channel);
     client->config = config;
     if(client->config.stateCallback)
         client->config.stateCallback(client, client->state);
@@ -110,8 +109,7 @@ UA_Client_secure_init(UA_Client* client, UA_ClientConfig config,
     (*securityPolicyFunction)(&client->securityPolicy,
                               client->securityPolicy.certificateVerification,
                               certificate, privateKey, config.logger);
-    client->channel.securityPolicy = &client->securityPolicy;
-    client->channel.securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
+
     client->config = config;
     if(client->config.stateCallback)
         client->config.stateCallback(client, client->state);
@@ -125,46 +123,12 @@ UA_Client_secure_init(UA_Client* client, UA_ClientConfig config,
 #ifndef UA_ENABLE_MULTITHREADING
     SLIST_INIT(&client->delayedClientCallbacks);
 #endif
-    /* Verify remote certificate if trust list given to the application */
-    if(trustListSize > 0) {
-        retval = client->channel.securityPolicy->certificateVerification->
-                 verifyCertificate(client->channel.securityPolicy->certificateVerification->context,
-                                   remoteCertificate);
-        if(retval != UA_STATUSCODE_GOOD) {
-            UA_LOG_ERROR(client->channel.securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL,
-                         "Certificate verification failed with error %s", UA_StatusCode_name(retval));
-            return retval;
-        }
-
-    } else {
-        UA_LOG_WARNING(client->channel.securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
-                       "No PKI plugin set. Accepting all certificates");
-    }
 
-    const UA_SecurityPolicy *securityPolicy = (UA_SecurityPolicy *) &client->securityPolicy;
-    retval = client->securityPolicy.channelModule.newContext(securityPolicy, remoteCertificate,
-                                                             &client->channel.channelContext);
-
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_LOG_ERROR(client->channel.securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL,
-                     "New context creation failed with error %s", UA_StatusCode_name(retval));
-        return retval;
-    }
-
-    retval = UA_ByteString_copy(remoteCertificate, &client->channel.remoteCertificate);
-
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_LOG_ERROR(client->channel.securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL,
-                     "Copying byte string failed with error %s", UA_StatusCode_name(retval));
-        return retval;
-    }
-
-    UA_ByteString remoteCertificateThumbprint = {20, client->channel.remoteCertificateThumbprint};
-
-    /* Invoke remote certificate thumbprint */
-    retval = client->securityPolicy.asymmetricModule.
-             makeCertificateThumbprint(securityPolicy, &client->channel.remoteCertificate,
-                                       &remoteCertificateThumbprint);
+    /* Initialize the SecureChannel */
+    UA_SecureChannel_init(&client->channel);
+    client->channel.securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
+    retval = UA_SecureChannel_setSecurityPolicy(&client->channel, &client->securityPolicy,
+                                                remoteCertificate);
     return retval;
 }
 

+ 15 - 2
src/client/ua_client_connect.c

@@ -584,9 +584,22 @@ UA_Client_connectInternal(UA_Client *client, const char *endpointUrl,
         goto cleanup;
     }
 
-    /* Local nonce set and generate sym keys */
-    retval |= UA_SecureChannel_generateLocalNonce(&client->channel);
+    /* Set the channel SecurityMode if not done so far */
+    if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID)
+        client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;
+
+    /* Set the channel SecurityPolicy if not done so far */
+    if(!client->channel.securityPolicy) {
+        UA_ByteString remoteCertificate = UA_BYTESTRING_NULL;
+        retval = UA_SecureChannel_setSecurityPolicy(&client->channel,
+                                                    &client->securityPolicy,
+                                                    &remoteCertificate);
+        if(retval != UA_STATUSCODE_GOOD)
+            return retval;
+    }
 
+    /* Local nonce set and generate sym keys */
+    retval = UA_SecureChannel_generateLocalNonce(&client->channel);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 

+ 14 - 0
src/client/ua_client_connect_async.c

@@ -574,6 +574,20 @@ UA_Client_connectInternalAsync(UA_Client *client, const char *endpointUrl,
         goto cleanup;
     }
 
+    /* Set the channel SecurityMode if not done so far */
+    if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID)
+        client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;
+
+    /* Set the channel SecurityPolicy if not done so far */
+    if(!client->channel.securityPolicy) {
+        UA_ByteString remoteCertificate = UA_BYTESTRING_NULL;
+        retval = UA_SecureChannel_setSecurityPolicy(&client->channel,
+                                                    &client->securityPolicy,
+                                                    &remoteCertificate);
+        if(retval != UA_STATUSCODE_GOOD)
+            return retval;
+    }
+
     client->asyncConnectCall.callback = callback;
     client->asyncConnectCall.userdata = userdata;
 

+ 4 - 2
src/server/ua_securechannel_manager.c

@@ -121,8 +121,10 @@ UA_SecureChannelManager_create(UA_SecureChannelManager *const cm, UA_Connection
 
     /* Create the channel context and parse the sender (remote) certificate used for the
      * secureChannel. */
-    UA_StatusCode retval = UA_SecureChannel_init(&entry->channel, securityPolicy,
-                                                 &asymHeader->senderCertificate);
+    UA_SecureChannel_init(&entry->channel);
+    UA_StatusCode retval =
+        UA_SecureChannel_setSecurityPolicy(&entry->channel, securityPolicy,
+                                           &asymHeader->senderCertificate);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_free(entry);
         return retval;

+ 13 - 8
src/ua_securechannel.c

@@ -38,18 +38,23 @@ UA_StatusCode sendAsym_sendFailure;
 UA_StatusCode processSym_seqNumberFailure;
 #endif
 
-UA_StatusCode
-UA_SecureChannel_init(UA_SecureChannel *channel,
-                      const UA_SecurityPolicy *securityPolicy,
-                      const UA_ByteString *remoteCertificate) {
-    if(channel == NULL || securityPolicy == NULL || remoteCertificate == NULL)
-        return UA_STATUSCODE_BADINTERNALERROR;
-
+void
+UA_SecureChannel_init(UA_SecureChannel *channel) {
     /* Linked lists are also initialized by zeroing out */
     memset(channel, 0, sizeof(UA_SecureChannel));
     channel->state = UA_SECURECHANNELSTATE_FRESH;
-    channel->securityPolicy = securityPolicy;
+    TAILQ_INIT(&channel->messages);
+}
 
+UA_StatusCode
+UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel,
+                                   const UA_SecurityPolicy *securityPolicy,
+                                   const UA_ByteString *remoteCertificate) {
+    /* Is a policy already configured? */
+    if(channel->securityPolicy)
+        return UA_STATUSCODE_BADINTERNALERROR;
+    
+    channel->securityPolicy = securityPolicy;
     UA_StatusCode retval;
     if(channel->securityPolicy->certificateVerification != NULL) {
         retval = channel->securityPolicy->certificateVerification->

+ 5 - 3
src/ua_securechannel.h

@@ -98,10 +98,12 @@ struct UA_SecureChannel {
     UA_MessageQueue messages;
 };
 
+void UA_SecureChannel_init(UA_SecureChannel *channel);
+
 UA_StatusCode
-UA_SecureChannel_init(UA_SecureChannel *channel,
-                      const UA_SecurityPolicy *securityPolicy,
-                      const UA_ByteString *remoteCertificate);
+UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel,
+                                   const UA_SecurityPolicy *securityPolicy,
+                                   const UA_ByteString *remoteCertificate);
 
 /* Remove (partially) received unprocessed messages */
 void UA_SecureChannel_deleteMessages(UA_SecureChannel *channel);

+ 4 - 2
tests/check_securechannel.c

@@ -44,7 +44,8 @@ static key_sizes keySizes;
 static void
 setup_secureChannel(void) {
     TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled, &keySizes);
-    UA_SecureChannel_init(&testChannel, &dummyPolicy, &dummyCertificate);
+    UA_SecureChannel_init(&testChannel);
+    UA_SecureChannel_setSecurityPolicy(&testChannel, &dummyPolicy, &dummyCertificate);
 
     testingConnection = createDummyConnection(65535, &sentData);
     UA_Connection_attachSecureChannel(&testingConnection, &testChannel);
@@ -97,7 +98,8 @@ START_TEST(SecureChannel_initAndDelete)
         UA_StatusCode retval;
 
         UA_SecureChannel channel;
-        retval = UA_SecureChannel_init(&channel, &dummyPolicy, &dummyCertificate);
+        UA_SecureChannel_init(&channel);
+        retval = UA_SecureChannel_setSecurityPolicy(&channel, &dummyPolicy, &dummyCertificate);
 
         ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Expected StatusCode to be good");
         ck_assert_msg(channel.state == UA_SECURECHANNELSTATE_FRESH, "Expected state to be fresh");

+ 2 - 1
tests/server/check_server_readspeed.c

@@ -31,7 +31,8 @@ static void setup(void) {
     server = UA_Server_new(config);
 
     TestingPolicy(&dummyPolicy, UA_BYTESTRING_NULL, &funcsCalled, &keySizes);
-    UA_SecureChannel_init(&testChannel, &dummyPolicy, &UA_BYTESTRING_NULL);
+    UA_SecureChannel_init(&testChannel);
+    UA_SecureChannel_setSecurityPolicy(&testChannel, &dummyPolicy, &UA_BYTESTRING_NULL);
 
     testingConnection = createDummyConnection(65535, NULL);
     UA_Connection_attachSecureChannel(&testingConnection, &testChannel);