Files
open62541/tests/encryption/check_encryption_basic256.c
basyskom-jvoe 4492548ee3 fix(plugin): Improve PEM support for mbedTLS and add tests (#3856)
* Add null terminator before parsing certificates and keys

mbedTLS expects PEM data to be null terminated, the length
parameter must include the null terminator.

By adding the null terminator inside open62541, an application
doesn't have to care what type of certificate or key is used.

* Extend encryption tests

- Add test for security policy Basic256
- Add test with PEM encoded certificate and key

* Fix amalgamation build for ua_pki_default.c

Including securitypolicy_mbedtls_common.h is not possible because
it is added to the amalgamation after ua_pki_default.c
2020-08-27 17:23:47 +02:00

280 lines
9.4 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2019 (c) Kalycito Infotech Private Limited
*
*/
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/securitypolicy.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>
#include "client/ua_client_internal.h"
#include "ua_server_internal.h"
#include <stdio.h>
#include <stdlib.h>
#include "certificates.h"
#include "check.h"
#include "testing_clock.h"
#include "testing_networklayers.h"
#include "thread_wrapper.h"
UA_Server *server;
UA_Boolean running;
UA_ServerNetworkLayer nl;
THREAD_HANDLE server_thread;
THREAD_CALLBACK(serverloop) {
while(running)
UA_Server_run_iterate(server, true);
return 0;
}
static void setup(void) {
running = true;
/* Load certificate and private key */
UA_ByteString certificate;
certificate.length = CERT_DER_LENGTH;
certificate.data = CERT_DER_DATA;
UA_ByteString privateKey;
privateKey.length = KEY_DER_LENGTH;
privateKey.data = KEY_DER_DATA;
/* Load the trustlist */
size_t trustListSize = 0;
UA_ByteString *trustList = NULL;
/* Load the issuerList */
size_t issuerListSize = 0;
UA_ByteString *issuerList = NULL;
/* TODO test trustList
if(argc > 3)
trustListSize = (size_t)argc-3;
UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
for(size_t i = 0; i < trustListSize; i++)
trustList[i] = loadFile(argv[i+3]);
*/
/* Loading of a revocation list currently unsupported */
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
server = UA_Server_new();
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefaultWithSecurityPolicies(config, 4840, &certificate, &privateKey,
trustList, trustListSize,
issuerList, issuerListSize,
revocationList, revocationListSize);
/* Set the ApplicationUri used in the certificate */
UA_String_clear(&config->applicationDescription.applicationUri);
config->applicationDescription.applicationUri =
UA_STRING_ALLOC("urn:unconfigured:application");
for(size_t i = 0; i < trustListSize; i++)
UA_ByteString_deleteMembers(&trustList[i]);
UA_Server_run_startup(server);
THREAD_CREATE(server_thread, serverloop);
}
static void teardown(void) {
running = false;
THREAD_JOIN(server_thread);
UA_Server_run_shutdown(server);
UA_Server_delete(server);
}
START_TEST(encryption_connect) {
UA_Client *client = NULL;
UA_EndpointDescription* endpointArray = NULL;
size_t endpointArraySize = 0;
UA_ByteString *trustList = NULL;
size_t trustListSize = 0;
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
/* Load certificate and private key */
UA_ByteString certificate;
certificate.length = CERT_DER_LENGTH;
certificate.data = CERT_DER_DATA;
ck_assert_int_ne(certificate.length, 0);
UA_ByteString privateKey;
privateKey.length = KEY_DER_LENGTH;
privateKey.data = KEY_DER_DATA;
ck_assert_int_ne(privateKey.length, 0);
/* The Get endpoint (discovery service) is done with
* security mode as none to see the server's capability
* and certificate */
client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
ck_assert(client != NULL);
UA_StatusCode retval = UA_Client_getEndpoints(client, "opc.tcp://localhost:4840",
&endpointArraySize, &endpointArray);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert(endpointArraySize > 0);
UA_Array_delete(endpointArray, endpointArraySize,
&UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
/* TODO test trustList Load revocationList is not supported now
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_Client_delete(client);
/* Secure client initialization */
client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
trustList, trustListSize,
revocationList, revocationListSize);
cc->securityPolicyUri =
UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256");
ck_assert(client != NULL);
for(size_t deleteCount = 0; deleteCount < trustListSize; deleteCount++) {
UA_ByteString_deleteMembers(&trustList[deleteCount]);
}
/* Secure client connect */
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_deleteMembers(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
START_TEST(encryption_connect_pem) {
UA_Client *client = NULL;
UA_EndpointDescription* endpointArray = NULL;
size_t endpointArraySize = 0;
UA_ByteString *trustList = NULL;
size_t trustListSize = 0;
UA_ByteString *revocationList = NULL;
size_t revocationListSize = 0;
/* Load certificate and private key */
UA_ByteString certificate;
certificate.length = CERT_PEM_LENGTH;
certificate.data = CERT_PEM_DATA;
ck_assert_int_ne(certificate.length, 0);
UA_ByteString privateKey;
privateKey.length = KEY_PEM_LENGTH;
privateKey.data = KEY_PEM_DATA;
ck_assert_int_ne(privateKey.length, 0);
/* The Get endpoint (discovery service) is done with
* security mode as none to see the server's capability
* and certificate */
client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
ck_assert(client != NULL);
UA_StatusCode retval = UA_Client_getEndpoints(client, "opc.tcp://localhost:4840",
&endpointArraySize, &endpointArray);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert(endpointArraySize > 0);
UA_Array_delete(endpointArray, endpointArraySize,
&UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
/* TODO test trustList Load revocationList is not supported now
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_Client_delete(client);
/* Secure client initialization */
client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
trustList, trustListSize,
revocationList, revocationListSize);
cc->securityPolicyUri =
UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256");
ck_assert(client != NULL);
for(size_t deleteCount = 0; deleteCount < trustListSize; deleteCount++) {
UA_ByteString_deleteMembers(&trustList[deleteCount]);
}
/* Secure client connect */
retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant val;
UA_Variant_init(&val);
UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
UA_Variant_deleteMembers(&val);
UA_Client_disconnect(client);
UA_Client_delete(client);
}
END_TEST
static Suite* testSuite_encryption(void) {
Suite *s = suite_create("Encryption");
TCase *tc_encryption = tcase_create("Encryption basic256");
tcase_add_checked_fixture(tc_encryption, setup, teardown);
#ifdef UA_ENABLE_ENCRYPTION
tcase_add_test(tc_encryption, encryption_connect);
tcase_add_test(tc_encryption, encryption_connect_pem);
#endif /* UA_ENABLE_ENCRYPTION */
suite_add_tcase(s,tc_encryption);
return s;
}
int main(void) {
Suite *s = testSuite_encryption();
SRunner *sr = srunner_create(s);
srunner_set_fork_status(sr, CK_NOFORK);
srunner_run_all(sr,CK_NORMAL);
int number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}