Skip to content

Commit

Permalink
feat(server): Implement a transaction structure for updating trust li…
Browse files Browse the repository at this point in the history
…st and server certificates
  • Loading branch information
NoelGraf committed Jun 5, 2024
1 parent d42454e commit 68d7b1f
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
25 changes: 25 additions & 0 deletions include/open62541/plugin/certificategroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ struct UA_CertificateGroup {
void (*clear)(UA_CertificateGroup *certGroup);
};

struct UA_Transaction;
typedef struct UA_Transaction UA_Transaction;

struct UA_Transaction {
UA_NodeId sessionId;

size_t certGroupSize;
UA_CertificateGroup *certGroups;

/* The entries in the arrays are related to each other at the same index. */
size_t serverCertSize;
UA_ByteString *certificates;
UA_ByteString *privateKeys;
UA_NodeId *certificateGroups;
UA_NodeId *certificateTypes;
};

/* Returns the appropriate CertificateGroup from the transaction.
* If the CertificateGroup does not exist in the transaction, it will be created. */
UA_CertificateGroup*
UA_Transaction_getCertificateGroup(UA_Transaction *transaction, const UA_CertificateGroup *certGroup);

void
UA_Transaction_clear(UA_Transaction *transaction);

/* Verify that the certificate has the applicationURI in the subject name. */
UA_EXPORT UA_StatusCode
UA_CertificateUtils_verifyApplicationURI(UA_RuleHandling ruleHandling,
Expand Down
73 changes: 73 additions & 0 deletions src/server/ua_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* Copyright 2019 (c) Kalycito Infotech Private Limited
* Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
* Copyright 2022 (c) Fraunhofer IOSB (Author: Andreas Ebner)
* Copyright 2024 (c) Fraunhofer IOSB (Author: Noel Graf)
*/

#include "ua_server_internal.h"
Expand Down Expand Up @@ -544,6 +545,78 @@ notifySecureChannelsStopped(UA_Server *server, struct UA_ServerComponent *sc,
}
}

UA_StatusCode UA_EXPORT
UA_Server_applyChanges(UA_Server *server) {
UA_StatusCode retval = UA_STATUSCODE_GOOD;
if(server->transaction == NULL)
return UA_STATUSCODE_BADNOTHINGTODO;

UA_Transaction *transaction = server->transaction;

/* Apply Trust list changes */
if(transaction->certGroupSize > 0) {
for(size_t i = 0; i < transaction->certGroupSize; i++) {
UA_CertificateGroup transactionCertGroup = transaction->certGroups[i];
UA_TrustListDataType trustList;
UA_TrustListDataType_init(&trustList);
trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL;
transactionCertGroup.getTrustList(&transactionCertGroup, &trustList);

UA_NodeId defaultApplicationGroup =
UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST);
UA_NodeId defaultUserTokenGroup =
UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST);
if(UA_NodeId_equal(&transactionCertGroup.certificateGroupId, &defaultApplicationGroup)) {
server->config.secureChannelPKI.setTrustList(&server->config.secureChannelPKI, &trustList);
}
if(UA_NodeId_equal(&transactionCertGroup.certificateGroupId, &defaultUserTokenGroup)) {
server->config.sessionPKI.setTrustList(&server->config.sessionPKI, &trustList);
}
UA_TrustListDataType_clear(&trustList);
}
}

/* Apply Server certificate changes */
if(transaction->serverCertSize > 0) {
for(size_t i = 0; i < transaction->serverCertSize; i++) {
UA_NodeId certGroupId = transaction->certificateGroups[i];
UA_NodeId certTypeId = transaction->certificateTypes[i];

for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
UA_SecurityPolicy *sp = &server->config.securityPolicies[i];
UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);

if(!UA_NodeId_equal(&certGroupId, &sp->certificateGroupId) ||
!UA_NodeId_equal(&certTypeId, &sp->certificateTypeId)) {
continue;
}
retval = sp->updateCertificateAndPrivateKey(sp, transaction->certificates[i],
transaction->privateKeys[i]);
if(retval != UA_STATUSCODE_GOOD)
return retval;
}
for(size_t i = 0; i < server->config.endpointsSize; i++) {
UA_EndpointDescription *ed = &server->config.endpoints[i];
UA_SecurityPolicy *sp = getSecurityPolicyByUri(server, &server->config.endpoints[i].securityPolicyUri);
UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);

if(!UA_NodeId_equal(&certGroupId, &sp->certificateGroupId) ||
!UA_NodeId_equal(&certTypeId, &sp->certificateTypeId)) {
continue;
}

UA_String_clear(&ed->serverCertificate);
UA_String_copy(&sp->localCertificate, &ed->serverCertificate);
}
}
}

UA_Transaction_clear(transaction);
transaction = NULL;

return retval;
}

UA_StatusCode
UA_Server_updateCertificate(UA_Server *server,
const UA_ByteString *oldCertificate,
Expand Down
3 changes: 3 additions & 0 deletions src/server/ua_server_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ struct UA_Server {
/* Statistics */
UA_SecureChannelStatistics secureChannelStatistics;
UA_ServerDiagnosticsSummaryDataType serverDiagnosticsSummary;

/* Transaction for certificate management */
UA_Transaction *transaction;
};

/***********************/
Expand Down

0 comments on commit 68d7b1f

Please sign in to comment.