Browse Source

[FIX] Trust list verification for secure client application

 - Update UA_ByteString_allocBuffer() to UA_STACKARRAY() in the files
   examples/encryption/client_basic128rsa15.c and examples/encryption/
   client_basic256sha256.c.
 - Handle return value for remote certificate verification in
   ua_client.c file.
 - Update create_self-signed.py to generate CA certificate in .der
   format.

Change-Id: I6e84694c99c561d237ecbafb63b957d19c2e74c9
Signed-off-by: Sharavanan A R <sharavanan.ar@kalycito.com>
Sharavanan A R 6 years ago
parent
commit
6d7f08b641

+ 4 - 10
examples/encryption/client_basic128rsa15.c

@@ -30,7 +30,6 @@ int main(int argc, char* argv[]) {
     UA_Client*              client             = NULL;
     UA_ByteString*          remoteCertificate  = NULL;
     UA_StatusCode           retval             = UA_STATUSCODE_GOOD;
-    UA_ByteString*          trustList          = NULL;
     size_t                  trustListSize      = 0;
     UA_ByteString*          revocationList     = NULL;
     size_t                  revocationListSize = 0;
@@ -99,17 +98,12 @@ int main(int argc, char* argv[]) {
     UA_Client_delete(client); /* Disconnects the client internally */
 
     /* Load the trustList. Load revocationList is not supported now */
-    if(argc > MIN_ARGS) {
+    if(argc > MIN_ARGS)
         trustListSize = (size_t)argc-MIN_ARGS;
-        retval = UA_ByteString_allocBuffer(trustList, trustListSize);
-        if(retval != UA_STATUSCODE_GOOD) {
-            cleanupClient(client, remoteCertificate);
-            return (int)retval;
-        }
 
-        for(size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++) {
-            trustList[trustListCount] = loadFile(argv[trustListCount+3]);
-        }
+    UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
+    for(size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++) {
+        trustList[trustListCount] = loadFile(argv[trustListCount+3]);
     }
 
     /* Secure client initialization */

+ 4 - 10
examples/encryption/client_basic256sha256.c

@@ -30,7 +30,6 @@ int main(int argc, char* argv[]) {
     UA_Client*              client             = NULL;
     UA_ByteString*          remoteCertificate  = NULL;
     UA_StatusCode           retval             = UA_STATUSCODE_GOOD;
-    UA_ByteString*          trustList          = NULL;
     size_t                  trustListSize      = 0;
     UA_ByteString*          revocationList     = NULL;
     size_t                  revocationListSize = 0;
@@ -99,17 +98,12 @@ int main(int argc, char* argv[]) {
     UA_Client_delete(client); /* Disconnects the client internally */
 
     /* Load the trustList. Load revocationList is not supported now */
-    if(argc > MIN_ARGS) {
+    if(argc > MIN_ARGS)
         trustListSize = (size_t)argc-MIN_ARGS;
-        retval = UA_ByteString_allocBuffer(trustList, trustListSize);
-        if(retval != UA_STATUSCODE_GOOD) {
-            cleanupClient(client, remoteCertificate);
-            return (int)retval;
-        }
 
-        for(size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++) {
-            trustList[trustListCount] = loadFile(argv[trustListCount+3]);
-        }
+    UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
+    for(size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++) {
+        trustList[trustListCount] = loadFile(argv[trustListCount+3]);
     }
 
     /* Secure client initialization */

+ 21 - 5
src/client/ua_client.c

@@ -92,8 +92,11 @@ UA_Client_secure_init(UA_Client* client, UA_ClientConfig config,
                                          trustList, trustListSize,
                                          revocationList, revocationListSize);
 
-    if(retval != UA_STATUSCODE_GOOD)
-         return retval;
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_LOG_ERROR(client->channel.securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL,
+                     "Trust list parsing failed with error %s", UA_StatusCode_name(retval));
+        return retval;
+    }
 
     /* Initiate client security policy */
     (*securityPolicyFunction)(&client->securityPolicy,
@@ -105,10 +108,17 @@ UA_Client_secure_init(UA_Client* client, UA_ClientConfig config,
     if(client->config.stateCallback)
         client->config.stateCallback(client, client->state);
 
-    if(client->channel.securityPolicy->certificateVerification != NULL) {
+    /* 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");
@@ -118,13 +128,19 @@ UA_Client_secure_init(UA_Client* client, UA_ClientConfig config,
     retval = client->securityPolicy.channelModule.newContext(securityPolicy, remoteCertificate,
                                                              &client->channel.channelContext);
 
-    if(retval != UA_STATUSCODE_GOOD)
+    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)
+    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};
 

+ 3 - 0
tools/certs/create_self-signed.py

@@ -52,6 +52,9 @@ os.system("""openssl x509 -req \
     -extensions v3_ca""".format(openssl_conf))
 os.system("openssl x509 -in localhost.crt -outform der -out server_cert.der")
 os.system("openssl rsa -inform PEM -in localhost.key -outform DER -out server_key.der")
+# Convert certificate authority(CA) file 'ca.crt' into DER encoded form
+# to provide as trust list input
+os.system("openssl x509 -in ca.crt -outform der -out ca_cert.der")
 
 os.remove("localhost.key")
 os.remove("localhost.crt")