Coverage Report

Created: 2025-12-14 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541/src/ua_securechannel_crypto.c
Line
Count
Source
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
 *
5
 *    Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6
 *    Copyright 2014, 2016-2017 (c) Florian Palm
7
 *    Copyright 2015-2016 (c) Sten GrĂ¼ner
8
 *    Copyright 2015 (c) Oleksiy Vasylyev
9
 *    Copyright 2016 (c) TorbenD
10
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
11
 *    Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
12
 */
13
14
#include "open62541/transport_generated.h"
15
#include "ua_securechannel.h"
16
#include "ua_types_encoding_binary.h"
17
18
UA_StatusCode
19
0
UA_SecureChannel_generateLocalNonce(UA_SecureChannel *channel) {
20
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
21
0
    UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
22
0
    UA_LOG_DEBUG_CHANNEL(sp->logger, channel, "Generating new local nonce");
23
24
    /* Is the length of the previous nonce correct? */
25
0
    size_t nonceLength = sp->symmetricModule.secureChannelNonceLength;
26
0
    if(channel->localNonce.length != nonceLength) {
27
0
        UA_ByteString_clear(&channel->localNonce);
28
0
        UA_StatusCode res = UA_ByteString_allocBuffer(&channel->localNonce, nonceLength);
29
0
        UA_CHECK_STATUS(res, return res);
30
0
    }
31
32
    /* Generate the nonce */
33
0
    return sp->symmetricModule.generateNonce(sp->policyContext, &channel->localNonce);
34
0
}
35
36
UA_StatusCode
37
0
UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *channel) {
38
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
39
0
    UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
40
0
    UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new local keys");
41
42
0
    void *cc = channel->channelContext;
43
0
    const UA_SecurityPolicyChannelModule *cm = &sp->channelModule;
44
0
    const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule;
45
0
    const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule;
46
47
    /* Generate symmetric key buffer of the required length. The block size is
48
     * identical for local/remote. */
49
0
    UA_ByteString buf;
50
0
    size_t encrKL = crm->encryptionAlgorithm.getLocalKeyLength(cc);
51
0
    size_t encrBS = crm->encryptionAlgorithm.getRemoteBlockSize(cc);
52
0
    size_t signKL = crm->signatureAlgorithm.getLocalKeyLength(cc);
53
0
    if(encrBS + signKL + encrKL == 0)
54
0
        return UA_STATUSCODE_GOOD; /* No keys to generate */
55
56
0
    UA_StatusCode retval = UA_ByteString_allocBuffer(&buf, encrBS + signKL + encrKL);
57
0
    UA_CHECK_STATUS(retval, return retval);
58
0
    UA_ByteString localSigningKey = {signKL, buf.data};
59
0
    UA_ByteString localEncryptingKey = {encrKL, &buf.data[signKL]};
60
0
    UA_ByteString localIv = {encrBS, &buf.data[signKL + encrKL]};
61
62
    /* TODO: Signal that no ECC salt is generated. Find a clean solution for this.  */
63
0
    buf.data[0] = 0x00;
64
65
    /* Generate key */
66
0
    retval = sm->generateKey(sp->policyContext, &channel->remoteNonce,
67
0
                             &channel->localNonce, &buf);
68
0
    UA_CHECK_STATUS(retval, goto error);
69
70
    /* Set the channel context */
71
0
    retval |= cm->setLocalSymSigningKey(cc, &localSigningKey);
72
0
    retval |= cm->setLocalSymEncryptingKey(cc, &localEncryptingKey);
73
0
    retval |= cm->setLocalSymIv(cc, &localIv);
74
75
0
 error:
76
0
    UA_CHECK_STATUS(retval, UA_LOG_WARNING_CHANNEL(sp->logger, channel,
77
0
                            "Could not generate local keys (statuscode: %s)",
78
0
                            UA_StatusCode_name(retval)));
79
0
    UA_ByteString_clear(&buf);
80
0
    return retval;
81
0
}
82
83
UA_StatusCode
84
0
generateRemoteKeys(const UA_SecureChannel *channel) {
85
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
86
0
    UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
87
0
    UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new remote keys");
88
89
0
    void *cc = channel->channelContext;
90
0
    const UA_SecurityPolicyChannelModule *cm = &sp->channelModule;
91
0
    const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule;
92
0
    const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule;
93
94
    /* Generate symmetric key buffer of the required length */
95
0
    UA_ByteString buf;
96
0
    size_t encrKL = crm->encryptionAlgorithm.getRemoteKeyLength(cc);
97
0
    size_t encrBS = crm->encryptionAlgorithm.getRemoteBlockSize(cc);
98
0
    size_t signKL = crm->signatureAlgorithm.getRemoteKeyLength(cc);
99
0
    if(encrBS + signKL + encrKL == 0)
100
0
        return UA_STATUSCODE_GOOD; /* No keys to generate */
101
102
0
    UA_StatusCode retval = UA_ByteString_allocBuffer(&buf, encrBS + signKL + encrKL);
103
0
    UA_CHECK_STATUS(retval, return retval);
104
0
    UA_ByteString remoteSigningKey = {signKL, buf.data};
105
0
    UA_ByteString remoteEncryptingKey = {encrKL, &buf.data[signKL]};
106
0
    UA_ByteString remoteIv = {encrBS, &buf.data[signKL + encrKL]};
107
108
    /* TODO: Signal that no ECC salt is generated. Find a clean solution for this.  */
109
0
    buf.data[0] = 0x00;
110
111
    /* Generate key */
112
0
    retval = sm->generateKey(sp->policyContext, &channel->localNonce,
113
0
                             &channel->remoteNonce, &buf);
114
0
    UA_CHECK_STATUS(retval, goto error);
115
116
    /* Set the channel context */
117
0
    retval |= cm->setRemoteSymSigningKey(cc, &remoteSigningKey);
118
0
    retval |= cm->setRemoteSymEncryptingKey(cc, &remoteEncryptingKey);
119
0
    retval |= cm->setRemoteSymIv(cc, &remoteIv);
120
121
0
 error:
122
0
    UA_CHECK_STATUS(retval, UA_LOG_WARNING_CHANNEL(sp->logger, channel,
123
0
                            "Could not generate remote keys (statuscode: %s)",
124
0
                            UA_StatusCode_name(retval)));
125
0
    UA_ByteString_clear(&buf);
126
0
    return retval;
127
0
}
128
129
/***************************/
130
/* Send Asymmetric Message */
131
/***************************/
132
133
/* The length of the static header content */
134
0
#define UA_SECURECHANNEL_ASYMMETRIC_SECURITYHEADER_FIXED_LENGTH 12
135
136
size_t
137
0
calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) {
138
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
139
0
    UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
140
141
0
    size_t asymHeaderLength = UA_SECURECHANNEL_ASYMMETRIC_SECURITYHEADER_FIXED_LENGTH +
142
0
                              sp->policyUri.length;
143
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
144
0
        return asymHeaderLength;
145
146
    /* OPN is always encrypted even if the mode is sign only */
147
0
    asymHeaderLength += 20; /* Thumbprints are always 20 byte long */
148
0
    asymHeaderLength += sp->localCertificate.length;
149
0
    return asymHeaderLength;
150
0
}
151
152
UA_StatusCode
153
prependHeadersAsym(UA_SecureChannel *const channel, UA_Byte *header_pos,
154
                   const UA_Byte *buf_end, size_t totalLength,
155
                   size_t securityHeaderLength, UA_UInt32 requestId,
156
0
                   size_t *const encryptedLength) {
157
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
158
0
    UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
159
160
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE) {
161
0
        *encryptedLength = totalLength;
162
0
    } else {
163
0
        size_t dataToEncryptLength = totalLength -
164
0
            (UA_SECURECHANNEL_CHANNELHEADER_LENGTH + securityHeaderLength);
165
0
        size_t plainTextBlockSize = sp->asymmetricModule.cryptoModule.
166
0
            encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
167
0
        size_t encryptedBlockSize = sp->asymmetricModule.cryptoModule.
168
0
            encryptionAlgorithm.getRemoteBlockSize(channel->channelContext);
169
170
        /* Padding always fills up the last block */
171
0
        UA_assert(dataToEncryptLength % plainTextBlockSize == 0);
172
0
        size_t blocks = dataToEncryptLength / plainTextBlockSize;
173
0
        *encryptedLength = totalLength + blocks * (encryptedBlockSize - plainTextBlockSize);
174
0
    }
175
176
0
    UA_TcpMessageHeader messageHeader;
177
0
    messageHeader.messageTypeAndChunkType = UA_MESSAGETYPE_OPN + UA_CHUNKTYPE_FINAL;
178
0
    messageHeader.messageSize = (UA_UInt32)*encryptedLength;
179
0
    UA_UInt32 secureChannelId = channel->securityToken.channelId;
180
0
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
181
0
    retval |= UA_encodeBinaryInternal(&messageHeader,
182
0
                                      &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
183
0
                                      &header_pos, &buf_end, NULL, NULL, NULL);
184
0
    retval |= UA_UInt32_encodeBinary(&secureChannelId, &header_pos, buf_end);
185
0
    UA_CHECK_STATUS(retval, return retval);
186
187
0
    UA_AsymmetricAlgorithmSecurityHeader asymHeader;
188
0
    UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader);
189
0
    asymHeader.securityPolicyUri = sp->policyUri;
190
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
191
0
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
192
0
        asymHeader.senderCertificate = sp->localCertificate;
193
0
        asymHeader.receiverCertificateThumbprint.length = 20;
194
0
        asymHeader.receiverCertificateThumbprint.data = channel->remoteCertificateThumbprint;
195
0
    }
196
0
    retval = UA_encodeBinaryInternal(
197
0
        &asymHeader, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER],
198
0
        &header_pos, &buf_end, NULL, NULL, NULL);
199
0
    UA_CHECK_STATUS(retval, return retval);
200
201
    /* Increase the sequence number in the channel */
202
0
    channel->sendSequenceNumber++;
203
204
0
    UA_SequenceHeader seqHeader;
205
0
    seqHeader.requestId = requestId;
206
0
    seqHeader.sequenceNumber = channel->sendSequenceNumber;
207
0
    retval = UA_encodeBinaryInternal(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER],
208
0
                                     &header_pos, &buf_end, NULL, NULL, NULL);
209
0
    return retval;
210
0
}
211
212
void
213
hideBytesAsym(const UA_SecureChannel *channel, UA_Byte **buf_start,
214
0
              const UA_Byte **buf_end) {
215
    /* Set buf_start to the beginning of the payload body */
216
0
    *buf_start += UA_SECURECHANNEL_CHANNELHEADER_LENGTH;
217
0
    *buf_start += calculateAsymAlgSecurityHeaderLength(channel);
218
0
    *buf_start += UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH;
219
220
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
221
0
        return;
222
223
    /* Make space for the certificate */
224
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
225
0
    *buf_end -= sp->asymmetricModule.cryptoModule.signatureAlgorithm.
226
0
        getLocalSignatureSize(channel->channelContext);
227
228
    /* Block sizes depend on the remote key (certificate) */
229
0
    size_t plainTextBlockSize = sp->asymmetricModule.cryptoModule.
230
0
        encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
231
0
    size_t encryptedBlockSize = sp->asymmetricModule.cryptoModule.
232
0
        encryptionAlgorithm.getRemoteBlockSize(channel->channelContext);
233
0
    UA_Boolean extraPadding = (sp->asymmetricModule.cryptoModule.encryptionAlgorithm.
234
0
                               getRemoteKeyLength(channel->channelContext) > 2048);
235
236
    /* Compute the maximum number of encrypted blocks that can fit entirely
237
     * before the signature. From that compute the maximum usable plaintext
238
     * size. */
239
0
    size_t maxEncrypted = (size_t)(*buf_end - *buf_start) +
240
0
        UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH;
241
0
    size_t max_blocks = maxEncrypted / encryptedBlockSize;
242
0
    size_t paddingBytes = (UA_LIKELY(!extraPadding)) ? 1u : 2u;
243
0
    *buf_end = *buf_start + (max_blocks * plainTextBlockSize) -
244
0
        UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH - paddingBytes;
245
0
}
246
247
/* Assumes that pos can be advanced to the end of the current block */
248
void
249
padChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cm,
250
0
         const UA_Byte *start, UA_Byte **pos) {
251
0
    const size_t bytesToWrite = (uintptr_t)*pos - (uintptr_t)start;
252
0
    size_t signatureSize = cm->signatureAlgorithm.
253
0
        getLocalSignatureSize(channel->channelContext);
254
0
    size_t plainTextBlockSize = cm->encryptionAlgorithm.
255
0
        getRemotePlainTextBlockSize(channel->channelContext);
256
0
    UA_Boolean extraPadding = (cm->encryptionAlgorithm.
257
0
        getRemoteKeyLength(channel->channelContext) > 2048);
258
0
    size_t paddingBytes = (UA_LIKELY(!extraPadding)) ? 1u : 2u;
259
260
0
    size_t lastBlock = ((bytesToWrite + signatureSize + paddingBytes) % plainTextBlockSize);
261
0
    size_t paddingLength = (lastBlock != 0) ? plainTextBlockSize - lastBlock : 0;
262
263
0
    UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
264
0
                         "Add %lu bytes of padding plus %lu padding size bytes",
265
0
                         (long unsigned int)paddingLength,
266
0
                         (long unsigned int)paddingBytes);
267
268
    /* Write the padding. This is <= because the paddingSize byte also has to be
269
     * written */
270
0
    UA_Byte paddingByte = (UA_Byte)paddingLength;
271
0
    for(size_t i = 0; i <= paddingLength; ++i) {
272
0
        **pos = paddingByte;
273
0
        ++*pos;
274
0
    }
275
276
    /* Write the extra padding byte if required */
277
0
    if(extraPadding) {
278
0
        **pos = (UA_Byte)(paddingLength >> 8u);
279
0
        ++*pos;
280
0
    }
281
0
}
282
283
UA_StatusCode
284
signAndEncryptAsym(UA_SecureChannel *channel, size_t preSignLength,
285
                   UA_ByteString *buf, size_t securityHeaderLength,
286
0
                   size_t totalLength) {
287
0
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
288
0
       channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
289
0
        return UA_STATUSCODE_GOOD;
290
291
    /* Sign message */
292
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
293
0
    const UA_ByteString dataToSign = {preSignLength, buf->data};
294
0
    size_t sigsize = sp->asymmetricModule.cryptoModule.signatureAlgorithm.
295
0
        getLocalSignatureSize(channel->channelContext);
296
0
    UA_ByteString signature = {sigsize, buf->data + preSignLength};
297
0
    UA_StatusCode retval = sp->asymmetricModule.cryptoModule.signatureAlgorithm.
298
0
        sign(channel->channelContext, &dataToSign, &signature);
299
0
    UA_CHECK_STATUS(retval, return retval);
300
301
    /* Specification part 6, 6.7.4: The OpenSecureChannel Messages are
302
     * signed and encrypted if the SecurityMode is not None (even if the
303
     * SecurityMode is SignOnly). */
304
0
    size_t unencrypted_length =
305
0
        UA_SECURECHANNEL_CHANNELHEADER_LENGTH + securityHeaderLength;
306
0
    UA_ByteString dataToEncrypt = {totalLength - unencrypted_length,
307
0
                                   &buf->data[unencrypted_length]};
308
0
    return sp->asymmetricModule.cryptoModule.encryptionAlgorithm.
309
0
        encrypt(channel->channelContext, &dataToEncrypt);
310
0
}
311
312
/**************************/
313
/* Send Symmetric Message */
314
/**************************/
315
316
UA_StatusCode
317
signAndEncryptSym(UA_MessageContext *messageContext,
318
0
                  size_t preSigLength, size_t totalLength) {
319
0
    const UA_SecureChannel *channel = messageContext->channel;
320
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
321
0
        return UA_STATUSCODE_GOOD;
322
323
    /* Sign */
324
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
325
0
    UA_ByteString dataToSign = messageContext->messageBuffer;
326
0
    dataToSign.length = preSigLength;
327
0
    UA_ByteString signature;
328
0
    signature.length = sp->symmetricModule.cryptoModule.signatureAlgorithm.
329
0
        getLocalSignatureSize(channel->channelContext);
330
0
    signature.data = messageContext->buf_pos;
331
0
    UA_StatusCode res = sp->symmetricModule.cryptoModule.signatureAlgorithm.
332
0
        sign(channel->channelContext, &dataToSign, &signature);
333
0
    UA_CHECK_STATUS(res, return res);
334
335
0
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
336
0
        return UA_STATUSCODE_GOOD;
337
338
    /* Encrypt */
339
0
    UA_ByteString dataToEncrypt;
340
0
    dataToEncrypt.data = messageContext->messageBuffer.data +
341
0
        UA_SECURECHANNEL_CHANNELHEADER_LENGTH +
342
0
        UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH;
343
0
    dataToEncrypt.length = totalLength -
344
0
        (UA_SECURECHANNEL_CHANNELHEADER_LENGTH +
345
0
         UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH);
346
0
    return sp->symmetricModule.cryptoModule.encryptionAlgorithm.
347
0
        encrypt(channel->channelContext, &dataToEncrypt);
348
0
}
349
350
void
351
0
setBufPos(UA_MessageContext *mc) {
352
    /* Forward the data pointer so that the payload is encoded after the message
353
     * header. This has to be a symmetric message because OPN (with asymmetric
354
     * encryption) does not support chunking. */
355
0
    mc->buf_pos = &mc->messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH];
356
0
    mc->buf_end = &mc->messageBuffer.data[mc->messageBuffer.length];
357
358
0
    if(mc->channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
359
0
        return;
360
361
0
    const UA_SecureChannel *channel = mc->channel;
362
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
363
0
    size_t sigsize = sp->symmetricModule.cryptoModule.signatureAlgorithm.
364
0
        getLocalSignatureSize(channel->channelContext);
365
0
    size_t plainBlockSize = sp->symmetricModule.cryptoModule.
366
0
        encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
367
368
    /* Assuming that for symmetric encryption the plainTextBlockSize ==
369
     * cypherTextBlockSize. For symmetric encryption the remote/local block
370
     * sizes are identical. */
371
0
    UA_assert(sp->symmetricModule.cryptoModule.encryptionAlgorithm.
372
0
              getRemoteBlockSize(channel->channelContext) == plainBlockSize);
373
374
    /* Leave enough space for the signature and padding */
375
0
    mc->buf_end -= sigsize;
376
0
    mc->buf_end -= mc->messageBuffer.length % plainBlockSize;
377
378
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
379
        /* Reserve space for the padding bytes */
380
0
        UA_Boolean extraPadding =
381
0
            (sp->symmetricModule.cryptoModule.encryptionAlgorithm.
382
0
             getRemoteKeyLength(channel->channelContext) > 2048);
383
0
        mc->buf_end -= (UA_LIKELY(!extraPadding)) ? 1 : 2;
384
0
    }
385
386
0
    UA_LOG_TRACE_CHANNEL(sp->logger, channel,
387
0
                         "Prepare a symmetric message buffer of length %lu "
388
0
                         "with a usable maximum payload length of %lu",
389
0
                         (long unsigned)mc->messageBuffer.length,
390
0
                         (long unsigned)((uintptr_t)mc->buf_end -
391
0
                                         (uintptr_t)mc->messageBuffer.data));
392
0
}
393
394
/****************************/
395
/* Process a received Chunk */
396
/****************************/
397
398
static size_t
399
decodePadding(const UA_SecureChannel *channel,
400
              const UA_SecurityPolicyCryptoModule *cryptoModule,
401
0
              const UA_ByteString *chunk, size_t sigsize) {
402
    /* Read the byte with the padding size */
403
0
    size_t paddingSize = chunk->data[chunk->length - sigsize - 1];
404
405
    /* Extra padding size */
406
0
    if(cryptoModule->encryptionAlgorithm.
407
0
       getLocalKeyLength(channel->channelContext) > 2048) {
408
0
        paddingSize <<= 8u;
409
0
        paddingSize += chunk->data[chunk->length - sigsize - 2];
410
0
        paddingSize += 1; /* Extra padding byte itself */
411
0
    }
412
413
    /* Add one since the paddingSize byte itself needs to be removed as well */
414
0
    return paddingSize + 1;
415
0
}
416
417
static UA_StatusCode
418
verifySignature(const UA_SecureChannel *channel,
419
                const UA_SecurityPolicyCryptoModule *cryptoModule,
420
0
                const UA_ByteString *chunk, size_t sigsize) {
421
0
    UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
422
0
                         "Verifying chunk signature");
423
0
    UA_CHECK(sigsize < chunk->length, return UA_STATUSCODE_BADSECURITYCHECKSFAILED);
424
0
    const UA_ByteString content = {chunk->length - sigsize, chunk->data};
425
0
    const UA_ByteString sig = {sigsize, chunk->data + chunk->length - sigsize};
426
0
    UA_StatusCode retval = cryptoModule->signatureAlgorithm.
427
0
        verify(channel->channelContext, &content, &sig);
428
0
    return retval;
429
0
}
430
431
/* Sets the payload to a pointer inside the chunk buffer. Returns the requestId
432
 * and the sequenceNumber */
433
UA_StatusCode
434
decryptAndVerifyChunk(const UA_SecureChannel *channel,
435
                      const UA_SecurityPolicyCryptoModule *cryptoModule,
436
                      UA_MessageType messageType, UA_ByteString *chunk,
437
0
                      size_t offset) {
438
    /* Decrypt the chunk */
439
0
    UA_StatusCode res = UA_STATUSCODE_GOOD;
440
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
441
0
       messageType == UA_MESSAGETYPE_OPN) {
442
0
        UA_ByteString cipher = {chunk->length - offset, chunk->data + offset};
443
0
        res = cryptoModule->encryptionAlgorithm.decrypt(channel->channelContext, &cipher);
444
0
        UA_CHECK_STATUS(res, return res);
445
0
        chunk->length = cipher.length + offset;
446
0
    }
447
448
    /* Does the message have a signature? */
449
0
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
450
0
       channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT &&
451
0
       messageType != UA_MESSAGETYPE_OPN)
452
0
        return UA_STATUSCODE_GOOD;
453
454
    /* Verify the chunk signature */
455
0
    size_t sigsize = cryptoModule->signatureAlgorithm.
456
0
        getRemoteSignatureSize(channel->channelContext);
457
0
    res = verifySignature(channel, cryptoModule, chunk, sigsize);
458
0
    UA_CHECK_STATUS(res,
459
0
       UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
460
0
                              "Could not verify the signature"); return res);
461
462
    /* Compute the padding if the payload is encrypted (not ECC policy) */
463
0
    size_t padSize = 0;
464
0
    if(((messageType != UA_MESSAGETYPE_OPN) && (channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)) ||
465
0
       (messageType == UA_MESSAGETYPE_OPN &&
466
0
        cryptoModule->encryptionAlgorithm.uri.length > 0 && 
467
0
        !isEccPolicy(channel->securityPolicy))) {
468
0
        padSize = decodePadding(channel, cryptoModule, chunk, sigsize);
469
0
        UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
470
0
                             "Calculated padding size to be %lu",
471
0
                             (long unsigned)padSize);
472
0
    }
473
474
    /* Verify the content length. The encrypted payload has to be at least 9
475
     * bytes long: 8 byte for the SequenceHeader and one byte for the actual
476
     * message */
477
0
    UA_CHECK(offset + padSize + sigsize + 9 < chunk->length,
478
0
             UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
479
0
                                    "Impossible padding value");
480
0
             return UA_STATUSCODE_BADSECURITYCHECKSFAILED);
481
482
    /* Hide the signature and padding */
483
0
    chunk->length -= (sigsize + padSize);
484
0
    return UA_STATUSCODE_GOOD;
485
0
}
486
487
UA_StatusCode
488
checkAsymHeader(UA_SecureChannel *channel,
489
0
                const UA_AsymmetricAlgorithmSecurityHeader *asymHeader) {
490
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
491
0
    if(!UA_String_equal(&sp->policyUri, &asymHeader->securityPolicyUri))
492
0
        return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
493
494
0
    return sp->asymmetricModule.
495
0
        compareCertificateThumbprint(sp, &asymHeader->receiverCertificateThumbprint);
496
497
    /* The certificate in the header is verified via the configured PKI plugin
498
     * as certificateVerification.verifyCertificate(...). We cannot do it here
499
     * because the client/server context is needed. */
500
0
}
501
502
UA_StatusCode
503
checkSymHeader(UA_SecureChannel *channel, const UA_UInt32 tokenId,
504
0
               UA_DateTime nowMonotonic) {
505
    /* If no match, try to revolve to the next token after a
506
     * RenewSecureChannel */
507
0
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
508
0
    UA_ChannelSecurityToken *token = &channel->securityToken;
509
0
    switch(channel->renewState) {
510
0
    case UA_SECURECHANNELRENEWSTATE_NORMAL:
511
0
    case UA_SECURECHANNELRENEWSTATE_SENT:
512
0
    default:
513
0
        break;
514
515
0
    case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER:
516
        /* Old token still in use */
517
0
        if(tokenId == channel->securityToken.tokenId)
518
0
            break;
519
520
        /* Not the new token */
521
0
        UA_CHECK(tokenId == channel->altSecurityToken.tokenId,
522
0
                 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
523
0
                                        "Unknown SecurityToken");
524
0
                 return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN);
525
526
        /* Roll over to the new token, generate new local and remote keys */
527
0
        channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
528
0
        channel->securityToken = channel->altSecurityToken;
529
0
        UA_ChannelSecurityToken_init(&channel->altSecurityToken);
530
0
        retval |= UA_SecureChannel_generateLocalKeys(channel);
531
0
        retval |= generateRemoteKeys(channel);
532
0
        UA_CHECK_STATUS(retval, return retval);
533
0
        break;
534
535
0
    case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT:
536
        /* The server is still using the old token. That's okay. */
537
0
        if(tokenId == channel->altSecurityToken.tokenId) {
538
0
            token = &channel->altSecurityToken;
539
0
            break;
540
0
        }
541
542
        /* Not the new token */
543
0
        UA_CHECK(tokenId == channel->securityToken.tokenId,
544
0
                 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
545
0
                                        "Unknown SecurityToken");
546
0
                 return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN);
547
548
        /* The remote server uses the new token for the first time. Delete the
549
         * old token and roll the remote key over. The local key already uses
550
         * the nonce pair from the last OPN exchange. */
551
0
        channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
552
0
        UA_ChannelSecurityToken_init(&channel->altSecurityToken);
553
0
        retval = generateRemoteKeys(channel);
554
0
        UA_CHECK_STATUS(retval, return retval);
555
0
    }
556
557
0
    UA_DateTime timeout = token->createdAt + (token->revisedLifetime * UA_DATETIME_MSEC);
558
0
    if(channel->state == UA_SECURECHANNELSTATE_OPEN &&
559
0
       timeout < nowMonotonic) {
560
0
        UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
561
0
                               "SecurityToken timed out");
562
0
        UA_SecureChannel_shutdown(channel, UA_SHUTDOWNREASON_TIMEOUT);
563
0
        return UA_STATUSCODE_BADSECURECHANNELCLOSED;
564
0
    }
565
566
0
    return UA_STATUSCODE_GOOD;
567
0
}
568
569
UA_Boolean
570
0
UA_SecureChannel_checkTimeout(UA_SecureChannel *channel, UA_DateTime nowMonotonic) {
571
    /* Compute the timeout date of the SecurityToken */
572
0
    UA_DateTime timeout = channel->securityToken.createdAt +
573
0
        (UA_DateTime)(channel->securityToken.revisedLifetime * UA_DATETIME_MSEC);
574
575
    /* The token has timed out. Try to do the token revolving now instead of
576
     * shutting the channel down.
577
     *
578
     * Part 4, 5.5.2 says: Servers shall use the existing SecurityToken to
579
     * secure outgoing Messages until the SecurityToken expires or the
580
     * Server receives a Message secured with a new SecurityToken.*/
581
0
    if(timeout < nowMonotonic && channel->renewState == UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER) {
582
        /* Revolve the token manually. This is otherwise done in checkSymHeader. */
583
0
        channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
584
0
        channel->securityToken = channel->altSecurityToken;
585
0
        UA_ChannelSecurityToken_init(&channel->altSecurityToken);
586
0
        UA_SecureChannel_generateLocalKeys(channel);
587
0
        generateRemoteKeys(channel);
588
589
        /* Use the timeout of the new SecurityToken */
590
0
        timeout = channel->securityToken.createdAt +
591
0
            (UA_DateTime)(channel->securityToken.revisedLifetime * UA_DATETIME_MSEC);
592
0
    }
593
594
0
    return (timeout < nowMonotonic);
595
0
}