diff --git a/CMakeLists.txt b/CMakeLists.txt index 99000918e60..9c78c6cdd31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # overwritten with more detailed information if git is available. set(OPEN62541_VER_MAJOR 1) set(OPEN62541_VER_MINOR 4) -set(OPEN62541_VER_PATCH 4) +set(OPEN62541_VER_PATCH 5) set(OPEN62541_VER_LABEL "-undefined") # like "-rc1" or "-g4538abcd" or "-g4538abcd-dirty" set(OPEN62541_VER_COMMIT "unknown-commit") diff --git a/plugins/crypto/mbedtls/certificategroup.c b/plugins/crypto/mbedtls/certificategroup.c index e17364010b5..d6f8f70472b 100644 --- a/plugins/crypto/mbedtls/certificategroup.c +++ b/plugins/crypto/mbedtls/certificategroup.c @@ -14,6 +14,7 @@ #ifdef UA_ENABLE_ENCRYPTION_MBEDTLS #include +#include #include #include #include @@ -240,232 +241,241 @@ reloadCertificates(UA_CertificateGroup *certGroup) { return UA_STATUSCODE_GOOD; } -static UA_StatusCode -verifyCertificate(UA_CertificateGroup *certGroup, const UA_ByteString *certificate) { - /* Check parameter */ - if (certGroup == NULL || certGroup->context == NULL) { - return UA_STATUSCODE_BADINTERNALERROR; - } +#define UA_MBEDTLS_MAX_CHAIN_LENGTH 10 +#define UA_MBEDTLS_MAX_DN_LENGTH 256 - MemoryCertStore *context = (MemoryCertStore *)certGroup->context; - if(context->reloadRequired) { - UA_StatusCode retval = reloadCertificates(certGroup); - if(retval != UA_STATUSCODE_GOOD) { - return retval; - } - context->reloadRequired = false; - } +/* We need to access some private fields below */ +#ifndef MBEDTLS_PRIVATE +#define MBEDTLS_PRIVATE(x) x +#endif +/* Is the certificate a CA? */ +static UA_Boolean +mbedtlsCheckCA(mbedtls_x509_crt *cert) { + /* The Basic Constraints extension must be set and the cert acts as CA */ + if(!(cert->MBEDTLS_PRIVATE(ext_types) & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) || + !cert->MBEDTLS_PRIVATE(ca_istrue)) + return false; + + /* The Key Usage extension must be set to cert signing and CRL issuing */ + if(!(cert->MBEDTLS_PRIVATE(ext_types) & MBEDTLS_X509_EXT_KEY_USAGE) || + mbedtls_x509_crt_check_key_usage(cert, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0 || + mbedtls_x509_crt_check_key_usage(cert, MBEDTLS_X509_KU_CRL_SIGN) != 0) + return false; + + return true; +} - /* Accept the certificate if the store is empty */ - if(context->trustedCertificates.raw.len == 0 && - context->issuerCertificates.raw.len == 0 && - context->trustedCrls.raw.len == 0 && - context->issuerCrls.raw.len == 0) { - UA_LOG_WARNING(certGroup->logging, UA_LOGCATEGORY_USERLAND, - "No certificate store configured. Accepting the certificate."); - return UA_STATUSCODE_GOOD; - } +static UA_Boolean +mbedtlsSameName(UA_String name, const mbedtls_x509_name *name2) { + char buf[UA_MBEDTLS_MAX_DN_LENGTH]; + int len = mbedtls_x509_dn_gets(buf, UA_MBEDTLS_MAX_DN_LENGTH, name2); + if(len < 0) + return false; + UA_String nameString = {(size_t)len, (UA_Byte*)buf}; + return UA_String_equal(&name, &nameString); +} - /* Parse the certificate */ - mbedtls_x509_crt remoteCertificate; +/* Return the first matching issuer candidate AFTER prev. + * This can return the cert itself if self-signed. */ +static mbedtls_x509_crt * +mbedtlsFindNextIssuer(MemoryCertStore *context, mbedtls_x509_crt *stack, + mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) { + char inbuf[UA_MBEDTLS_MAX_DN_LENGTH]; + int nameLen = mbedtls_x509_dn_gets(inbuf, UA_MBEDTLS_MAX_DN_LENGTH, &cert->issuer); + if(nameLen < 0) + return NULL; + UA_String issuerName = {(size_t)nameLen, (UA_Byte*)inbuf}; + do { + for(mbedtls_x509_crt *i = stack; i; i = i->next) { + if(prev) { + if(prev == i) + prev = NULL; /* This was the last issuer we tried to verify */ + continue; + } + /* Compare issuer name and subject name. + * Skip when the key does not match the signature. */ + if(mbedtlsSameName(issuerName, &i->subject) && + mbedtls_pk_can_do(&i->pk, cert->MBEDTLS_PRIVATE(sig_pk))) + return i; + } + /* Switch from the stack that came with the cert to the ctx->skIssue list */ + stack = (stack != &context->issuerCertificates) ? &context->issuerCertificates: NULL; + } while(stack); + return NULL; +} - /* Temporary Object to parse the trustList */ - mbedtls_x509_crt *tempCert = NULL; +static UA_Boolean +mbedtlsCheckRevoked(MemoryCertStore *context, mbedtls_x509_crt *cert) { + char inbuf[UA_MBEDTLS_MAX_DN_LENGTH]; + int nameLen = mbedtls_x509_dn_gets(inbuf, UA_MBEDTLS_MAX_DN_LENGTH, &cert->issuer); + if(nameLen < 0) + return true; + UA_String issuerName = {(size_t)nameLen, (UA_Byte*)inbuf}; + for(mbedtls_x509_crl *crl = &context->trustedCrls; crl; crl = crl->next) { + if(mbedtlsSameName(issuerName, &crl->issuer) && + mbedtls_x509_crt_is_revoked(cert, crl) != 0) + return true; + } + for(mbedtls_x509_crl *crl = &context->issuerCrls; crl; crl = crl->next) { + if(mbedtlsSameName(issuerName, &crl->issuer) && + mbedtls_x509_crt_is_revoked(cert, crl) != 0) + return true; + } + return false; +} - /* Temporary Object to parse the revocationList */ - mbedtls_x509_crl *tempCrl = NULL; +/* Verify that the public key of the issuer was used to sign the certificate */ +static UA_Boolean +mbedtlsCheckSignature(const mbedtls_x509_crt *cert, mbedtls_x509_crt *issuer) { + size_t hash_len; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + mbedtls_md_type_t md = cert->MBEDTLS_PRIVATE(sig_md); +#if !defined(MBEDTLS_USE_PSA_CRYPTO) + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md); + hash_len = mbedtls_md_get_size(md_info); + if(mbedtls_md(md_info, cert->tbs.p, cert->tbs.len, hash) != 0) + return false; +#else + if(psa_hash_compute(mbedtls_md_psa_alg_from_type(md), cert->tbs.p, + cert->tbs.len, hash, sizeof(hash), &hash_len) != PSA_SUCCESS) + return false; +#endif + const mbedtls_x509_buf *sig = &cert->MBEDTLS_PRIVATE(sig); + void *sig_opts = cert->MBEDTLS_PRIVATE(sig_opts); + mbedtls_pk_type_t pktype = cert->MBEDTLS_PRIVATE(sig_pk); + return (mbedtls_pk_verify_ext(pktype, sig_opts, &issuer->pk, md, + hash, hash_len, sig->p, sig->len) == 0); +} - /* Temporary Object to identify the parent CA when there is no intermediate CA */ - mbedtls_x509_crt *parentCert = NULL; +static UA_StatusCode +mbedtlsVerifyChain(MemoryCertStore *context, mbedtls_x509_crt *stack, mbedtls_x509_crt **old_issuers, + mbedtls_x509_crt *cert, int depth) { + /* Maxiumum chain length */ + if(depth == UA_MBEDTLS_MAX_CHAIN_LENGTH) + return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + + /* Verification Step: Validity Period */ + if(mbedtls_x509_time_is_future(&cert->valid_from) || + mbedtls_x509_time_is_past(&cert->valid_to)) + return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATETIMEINVALID : + UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID; + + /* Verification Step: Revocation Check */ + if(mbedtlsCheckRevoked(context, cert)) + return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATEREVOKED : + UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED; + + /* Return the most specific error code. BADCERTIFICATECHAININCOMPLETE is + * returned only if all possible chains are incomplete. */ + mbedtls_x509_crt *issuer = NULL; + UA_StatusCode ret = UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + while(ret != UA_STATUSCODE_GOOD) { + /* Find the issuer. This can return the same certificate if it is + * self-signed (subject == issuer). We come back here to try a different + * "path" if a subsequent verification fails. */ + issuer = mbedtlsFindNextIssuer(context, stack, cert, issuer); + if(!issuer) + break; + + /* Verification Step: Certificate Usage + * Can the issuer act as CA? Omit for self-signed leaf certificates. */ + if((depth > 0 || issuer != cert) && !mbedtlsCheckCA(issuer)) { + ret = UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED; + continue; + } - /* Temporary Object to identify the parent CA when there is intermediate CA */ - mbedtls_x509_crt *parentCert_2 = NULL; + /* Verification Step: Signature */ + if(!mbedtlsCheckSignature(cert, issuer)) { + ret = UA_STATUSCODE_BADCERTIFICATEINVALID; /* Wrong issuer, try again */ + continue; + } - /* Flag value to identify if the issuer certificate is found */ - int issuerKnown = 0; + /* The certificate is self-signed. We have arrived at the top of the + * chain. We check whether the certificate is trusted below. This is the + * only place where we return UA_STATUSCODE_BADCERTIFICATEUNTRUSTED. + * This signals that the chain is complete (but can be still + * untrusted). */ + if(issuer == cert || (cert->tbs.len == issuer->tbs.len && + memcmp(cert->tbs.p, issuer->tbs.p, cert->tbs.len) == 0)) { + ret = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED; + continue; + } - /* Flag value to identify if the parent certificate found */ - int parentFound = 0; + /* Detect (endless) loops of issuers. The last one can be skipped by the + * check for self-signed just before. */ + for(int i = 0; i < depth - 1; i++) { + if(old_issuers[i] == issuer) + return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + } + old_issuers[depth] = issuer; - mbedtls_x509_crt_init(&remoteCertificate); - int mbedErr = mbedtls_x509_crt_parse(&remoteCertificate, certificate->data, - certificate->length); - if(mbedErr) { - return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + /* We have found the issuer certificate used for the signature. Recurse + * to the next certificate in the chain (verify the current issuer). */ + ret = mbedtlsVerifyChain(context, stack, old_issuers, issuer, depth + 1); } - /* Verify */ - mbedtls_x509_crt_profile crtProfile = { - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256), - 0xFFFFFF, 0x000000, 128 * 8 // in bits - }; // TODO: remove magic numbers - - uint32_t flags = 0; - mbedErr = mbedtls_x509_crt_verify_with_profile(&remoteCertificate, - &context->trustedCertificates, - &context->trustedCrls, - &crtProfile, NULL, &flags, NULL, NULL); - - /* Flag to check if the remote certificate is trusted or not */ - int TRUSTED = 0; - - /* Check if the remoteCertificate is present in the trustList while mbedErr value is not zero */ - if(mbedErr && !(flags & MBEDTLS_X509_BADCERT_EXPIRED) && !(flags & MBEDTLS_X509_BADCERT_FUTURE)) { - for(tempCert = &context->trustedCertificates; tempCert != NULL; tempCert = tempCert->next) { - if(remoteCertificate.raw.len == tempCert->raw.len && - memcmp(remoteCertificate.raw.p, tempCert->raw.p, remoteCertificate.raw.len) == 0) { - TRUSTED = REMOTECERTIFICATETRUSTED; - break; - } + /* The chain is complete, but we haven't yet identified a trusted + * certificate "on the way down". Can we trust this certificate? */ + if(ret == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED) { + for(mbedtls_x509_crt *t = &context->trustedCertificates; t; t = t->next) { + if(cert->tbs.len == t->tbs.len && + memcmp(cert->tbs.p, t->tbs.p, cert->tbs.len) == 0) + return UA_STATUSCODE_GOOD; } } - /* If the remote certificate is present in the trustList then check if the issuer certificate - * of remoteCertificate is present in issuerList */ - if(TRUSTED && mbedErr) { - mbedErr = mbedtls_x509_crt_verify_with_profile(&remoteCertificate, - &context->issuerCertificates, - &context->issuerCrls, - &crtProfile, NULL, &flags, NULL, NULL); - - /* Check if the parent certificate has a CRL file available */ - if(!mbedErr) { - /* Flag value to identify if that there is an intermediate CA present */ - int dualParent = 0; - - /* Identify the topmost parent certificate for the remoteCertificate */ - for(parentCert = &context->issuerCertificates; parentCert != NULL; parentCert = parentCert->next ) { - if(memcmp(remoteCertificate.issuer_raw.p, parentCert->subject_raw.p, parentCert->subject_raw.len) == 0) { - for(parentCert_2 = &context->trustedCertificates; parentCert_2 != NULL; parentCert_2 = parentCert_2->next) { - if(memcmp(parentCert->issuer_raw.p, parentCert_2->subject_raw.p, parentCert_2->subject_raw.len) == 0) { - dualParent = DUALPARENT; - break; - } - } - parentFound = PARENTFOUND; - } - - if(parentFound == PARENTFOUND) - break; - } - - /* Check if there is an intermediate certificate between the topmost parent - * certificate and child certificate - * If yes the topmost parent certificate is to be checked whether it has a - * CRL file avaiable */ - if(dualParent == DUALPARENT && parentFound == PARENTFOUND) { - parentCert = parentCert_2; - } + return ret; +} - /* If a parent certificate is found traverse the revocationList and identify - * if there is any CRL file that corresponds to the parentCertificate */ - if(parentFound == PARENTFOUND) { - tempCrl = &context->issuerCrls; - while(tempCrl != NULL) { - if(tempCrl->version != 0 && - tempCrl->issuer_raw.len == parentCert->subject_raw.len && - memcmp(tempCrl->issuer_raw.p, - parentCert->subject_raw.p, - tempCrl->issuer_raw.len) == 0) { - issuerKnown = ISSUERKNOWN; - break; - } - - tempCrl = tempCrl->next; - } - - /* If the CRL file corresponding to the parent certificate is not present - * then return UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN */ - if(!issuerKnown) { - return UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN; - } - } - } +/* This follows Part 6, 6.1.3 Determining if a Certificate is trusted. + * It defines a sequence of steps for certificate verification. */ +static UA_StatusCode +verifyCertificate(UA_CertificateGroup *certGroup, const UA_ByteString *certificate) { + /* Check parameter */ + if (certGroup == NULL || certGroup->context == NULL) { + return UA_STATUSCODE_BADINTERNALERROR; } - else if(!mbedErr && !TRUSTED) { - /* This else if section is to identify if the parent certificate which is present in trustList - * has CRL file corresponding to it */ - - /* Identify the parent certificate of the remoteCertificate */ - for(parentCert = &context->trustedCertificates; parentCert != NULL; parentCert = parentCert->next) { - if(memcmp(remoteCertificate.issuer_raw.p, parentCert->subject_raw.p, parentCert->subject_raw.len) == 0) { - parentFound = PARENTFOUND; - break; - } - } - - /* If the parent certificate is found traverse the revocationList and identify - * if there is any CRL file that corresponds to the parentCertificate */ - if(parentFound == PARENTFOUND && - memcmp(remoteCertificate.issuer_raw.p, remoteCertificate.subject_raw.p, remoteCertificate.subject_raw.len) != 0) { - tempCrl = &context->trustedCrls; - while(tempCrl != NULL) { - if(tempCrl->version != 0 && - tempCrl->issuer_raw.len == parentCert->subject_raw.len && - memcmp(tempCrl->issuer_raw.p, - parentCert->subject_raw.p, - tempCrl->issuer_raw.len) == 0) { - issuerKnown = ISSUERKNOWN; - break; - } - - tempCrl = tempCrl->next; - } - - /* If the CRL file corresponding to the parent certificate is not present - * then return UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN */ - if(!issuerKnown) { - return UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN; - } + MemoryCertStore *context = (MemoryCertStore *)certGroup->context; + if(context->reloadRequired) { + UA_StatusCode retval = reloadCertificates(certGroup); + if(retval != UA_STATUSCODE_GOOD) { + return retval; } - + context->reloadRequired = false; } - // TODO: Extend verification - - /* This condition will check whether the certificate is a User certificate - * or a CA certificate. If the MBEDTLS_X509_KU_KEY_CERT_SIGN and - * MBEDTLS_X509_KU_CRL_SIGN of key_usage are set, then the certificate - * shall be condidered as CA Certificate and cannot be used to establish a - * connection. Refer the test case CTT/Security/Security Certificate Validation/029.js - * for more details */ -#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000 - if((remoteCertificate.key_usage & MBEDTLS_X509_KU_KEY_CERT_SIGN) && - (remoteCertificate.key_usage & MBEDTLS_X509_KU_CRL_SIGN)) { - return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED; - } -#else - if((remoteCertificate.private_key_usage & MBEDTLS_X509_KU_KEY_CERT_SIGN) && - (remoteCertificate.private_key_usage & MBEDTLS_X509_KU_CRL_SIGN)) { + /* Verification Step: Certificate Structure + * This parses the entire certificate chain contained in the bytestring. */ + mbedtls_x509_crt cert; + mbedtls_x509_crt_init(&cert); + int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, + certificate->length); + if(mbedErr) + return UA_STATUSCODE_BADCERTIFICATEINVALID; + + /* Verification Step: Certificate Usage + * Check whether the certificate is a User certificate or a CA certificate. + * Refer the test case CTT/Security/Security Certificate Validation/029.js + * for more details. */ + if(mbedtlsCheckCA(&cert)) { + mbedtls_x509_crt_free(&cert); return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED; } -#endif - UA_StatusCode retval = UA_STATUSCODE_GOOD; - if(mbedErr) { -#if UA_LOGLEVEL <= 400 - char buff[100]; - int len = mbedtls_x509_crt_verify_info(buff, 100, "", flags); - UA_LOG_WARNING(certGroup->logging, UA_LOGCATEGORY_SECURITYPOLICY, - "Verifying the certificate failed with error: %.*s", len-1, buff); -#endif - if(flags & (uint32_t)MBEDTLS_X509_BADCERT_NOT_TRUSTED) { - retval = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED; - } else if(flags & (uint32_t)MBEDTLS_X509_BADCERT_FUTURE || - flags & (uint32_t)MBEDTLS_X509_BADCERT_EXPIRED) { - retval = UA_STATUSCODE_BADCERTIFICATETIMEINVALID; - } else if(flags & (uint32_t)MBEDTLS_X509_BADCERT_REVOKED || - flags & (uint32_t)MBEDTLS_X509_BADCRL_EXPIRED) { - retval = UA_STATUSCODE_BADCERTIFICATEREVOKED; - } else { - retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; - } - } + /* These steps are performed outside of this method. + * Because we need the server or client context. + * - Security Policy + * - Host Name + * - URI */ - mbedtls_x509_crt_free(&remoteCertificate); - return retval; + /* Verification Step: Build Certificate Chain + * We perform the checks for each certificate inside. */ + mbedtls_x509_crt *old_issuers[UA_MBEDTLS_MAX_CHAIN_LENGTH]; + UA_StatusCode ret = mbedtlsVerifyChain(context, &cert, old_issuers, &cert, 0); + mbedtls_x509_crt_free(&cert); + return ret; } static UA_StatusCode @@ -477,10 +487,7 @@ MemoryCertStore_verifyCertificate(UA_CertificateGroup *certGroup, } UA_StatusCode retval = verifyCertificate(certGroup, certificate); - if(retval == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED || - retval == UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED || - retval == UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN || - retval == UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN) { + if(retval != UA_STATUSCODE_GOOD) { if(MemoryCertStore_addToRejectedList(certGroup, certificate) != UA_STATUSCODE_GOOD) { UA_LOG_WARNING(certGroup->logging, UA_LOGCATEGORY_SECURITYPOLICY, "Could not append certificate to rejected list"); diff --git a/plugins/crypto/openssl/certificategroup.c b/plugins/crypto/openssl/certificategroup.c index 2564a101fdc..feed027b7d8 100644 --- a/plugins/crypto/openssl/certificategroup.c +++ b/plugins/crypto/openssl/certificategroup.c @@ -258,44 +258,231 @@ reloadCertificates(UA_CertificateGroup *certGroup) { return UA_STATUSCODE_GOOD; } +/* Find binary substring. Taken and adjusted from + * http://tungchingkai.blogspot.com/2011/07/binary-strstr.html */ + +static const unsigned char * +bstrchr(const unsigned char *s, const unsigned char ch, size_t l) { + /* find first occurrence of c in char s[] for length l*/ + for(; l > 0; ++s, --l) { + if(*s == ch) + return s; + } + return NULL; +} + +static const unsigned char * +UA_Bstrstr(const unsigned char *s1, size_t l1, const unsigned char *s2, size_t l2) { + /* find first occurrence of s2[] in s1[] for length l1*/ + const unsigned char *ss1 = s1; + const unsigned char *ss2 = s2; + /* handle special case */ + if(l1 == 0) + return (NULL); + if(l2 == 0) + return s1; + + /* match prefix */ + for (; (s1 = bstrchr(s1, *s2, (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1)) != NULL && + (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1 != 0; ++s1) { + + /* match rest of prefix */ + const unsigned char *sc1, *sc2; + for (sc1 = s1, sc2 = s2; ;) + if (++sc2 >= ss2+l2) + return s1; + else if (*++sc1 != *sc2) + break; + } + return NULL; +} + +static const unsigned char openssl_PEM_PRE[28] = "-----BEGIN CERTIFICATE-----"; + +/* Extract the leaf certificate from a bytestring that may contain an entire chain */ +static X509 * +openSSLLoadLeafCertificate(UA_ByteString cert, size_t *offset) { + if(cert.length <= *offset) + return NULL; + cert.length -= *offset; + cert.data += *offset; + + /* Detect DER encoding. Extract the encoding length and cut. */ + if(cert.length >= 4 && cert.data[0] == 0x30 && cert.data[1] == 0x82) { + /* The certificate length is encoded after the magic bytes */ + size_t certLen = 4; /* Magic numbers + length bytes */ + certLen += (size_t)(((uint16_t)cert.data[2]) << 8); + certLen += cert.data[3]; + if(certLen > cert.length) + return NULL; + cert.length = certLen; + *offset += certLen; + const UA_Byte *dataPtr = cert.data; + return d2i_X509(NULL, &dataPtr, (long)cert.length); + } + + /* Assume PEM encoding. Detect multiple certificates and cut. */ + if(cert.length > 27 * 4) { + const unsigned char *match = + UA_Bstrstr(openssl_PEM_PRE, 27, &cert.data[27*2], cert.length - (27*2)); + if(match) + cert.length = (uintptr_t)(match - cert.data); + } + *offset += cert.length; + + BIO *bio = BIO_new_mem_buf((void *) cert.data, (int)cert.length); + X509 *result = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + return result; +} + +/* The bytestring might contain an entire certificate chain. The first + * stack-element is the leaf certificate itself. The remaining ones are + * potential issuer certificates. */ +static STACK_OF(X509) * +openSSLLoadCertificateStack(const UA_ByteString cert) { + size_t offset = 0; + X509 *x509 = NULL; + STACK_OF(X509) *result = sk_X509_new_null(); + if(!result) + return NULL; + while((x509 = openSSLLoadLeafCertificate(cert, &offset))) { + sk_X509_push(result, x509); + } + return result; +} + +/* Return the first matching issuer candidate AFTER prev */ +static X509 * +openSSLFindNextIssuer(MemoryCertStore *ctx, STACK_OF(X509) *stack, X509 *x509, X509 *prev) { + /* First check issuers from the stack - provided in the same bytestring as + * the certificate. This can also return x509 itself. */ + do { + int size = sk_X509_num(stack); + for(int i = 0; i < size; i++) { + X509 *candidate = sk_X509_value(stack, i); + if(prev) { + if(prev == candidate) + prev = NULL; /* This was the last issuer we tried to verify */ + continue; + } + /* This checks subject/issuer name and the key usage of the issuer. + * It does not verify the validity period and if the issuer key was + * used for the signature. We check that afterwards. */ + if(X509_check_issued(candidate, x509) == 0) + return candidate; + } + /* Switch to search in the ctx->skIssue list */ + stack = (stack != ctx->issuerCertificates) ? ctx->issuerCertificates : NULL; + } while(stack); + return NULL; +} + +static UA_Boolean +openSSLCheckRevoked(MemoryCertStore *ctx, X509 *cert) { + const ASN1_INTEGER *sn = X509_get0_serialNumber(cert); + const X509_NAME *in = X509_get_issuer_name(cert); + int size = sk_X509_CRL_num(ctx->crls); + for(int i = 0; i < size; i++) { + /* The crl contains a list of serial numbers from the same issuer */ + X509_CRL *crl = sk_X509_CRL_value(ctx->crls, i); + if(X509_NAME_cmp(in, X509_CRL_get_issuer(crl)) != 0) + continue; + STACK_OF(X509_REVOKED) *rs = X509_CRL_get_REVOKED(crl); + int rsize = sk_X509_REVOKED_num(rs); + for(int j = 0; j < rsize; j++) { + X509_REVOKED *r = sk_X509_REVOKED_value(rs, j); + if(ASN1_INTEGER_cmp(sn, X509_REVOKED_get0_serialNumber(r)) == 0) + return true; + } + } + return false; +} + +#define UA_OPENSSL_MAX_CHAIN_LENGTH 10 + static UA_StatusCode -UA_X509_Store_CTX_Error_To_UAError(int opensslErr) { - UA_StatusCode ret; - - switch (opensslErr) { - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_CRL_NOT_YET_VALID: - case X509_V_ERR_CRL_HAS_EXPIRED: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - ret = UA_STATUSCODE_BADCERTIFICATETIMEINVALID; - break; - case X509_V_ERR_CERT_REVOKED: - ret = UA_STATUSCODE_BADCERTIFICATEREVOKED; - break; - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: +openSSL_verifyChain(MemoryCertStore *ctx, STACK_OF(X509) *stack, X509 **old_issuers, + X509 *cert, int depth) { + /* Maxiumum chain length */ + if(depth == UA_OPENSSL_MAX_CHAIN_LENGTH) + return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + + /* Verification Step: Validity Period */ + ASN1_TIME *notBefore = X509_get_notBefore(cert); + ASN1_TIME *notAfter = X509_get_notAfter(cert); + if(X509_cmp_current_time(notBefore) != -1 || X509_cmp_current_time(notAfter) != 1) + return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATETIMEINVALID : + UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID; + + /* Verification Step: Revocation Check */ + if(openSSLCheckRevoked(ctx, cert)) + return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATEREVOKED : + UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED; + + /* Return the most specific error code. BADCERTIFICATECHAININCOMPLETE is + * returned only if all possible chains are incomplete. */ + X509 *issuer = NULL; + UA_StatusCode ret = UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + while(ret != UA_STATUSCODE_GOOD) { + /* Find the issuer. We jump back here to find a different path if a + * subsequent check fails. */ + issuer = openSSLFindNextIssuer(ctx, stack, cert, issuer); + if(!issuer) + break; + + /* Verification Step: Certificate Usage + * Can the issuer act as CA? Omit for self-signed leaf certificates. */ + if((depth > 0 || issuer != cert) && !X509_check_ca(issuer)) { + ret = UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED; + continue; + } + + /* Verification Step: Signature */ + int opensslRet = X509_verify(cert, X509_get0_pubkey(issuer)); + if(opensslRet == -1) { + return UA_STATUSCODE_BADCERTIFICATEINVALID; /* Ill-formed signature */ + } else if(opensslRet == 0) { + ret = UA_STATUSCODE_BADCERTIFICATEINVALID; /* Wrong issuer, try again */ + continue; + } + + /* The certificate is self-signed. We have arrived at the top of the + * chain. We check whether the certificate is trusted below. This is the + * only place where we return UA_STATUSCODE_BADCERTIFICATEUNTRUSTED. + * This signals that the chain is complete (but can be still + * untrusted). */ + if(cert == issuer || X509_cmp(cert, issuer) == 0) { ret = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED; - break; - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - ret = UA_STATUSCODE_BADSECURITYCHECKSFAILED; - break; - case X509_V_ERR_UNABLE_TO_GET_CRL: - ret = UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN; - break; - default: - ret = UA_STATUSCODE_BADCERTIFICATEINVALID; - break; + continue; + } + + /* Detect (endless) loops of issuers. The last one can be skipped by the + * check for self-signed just before. */ + for(int i = 0; i < depth; i++) { + if(old_issuers[i] == issuer) + return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE; + } + old_issuers[depth] = issuer; + + /* We have found the issuer certificate used for the signature. Recurse + * to the next certificate in the chain (verify the current issuer). */ + ret = openSSL_verifyChain(ctx, stack, old_issuers, issuer, depth + 1); + } + + /* Is the certificate in the trust list? If yes, then we are done. */ + if(ret == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED) { + for(int i = 0; i < sk_X509_num(ctx->trustedCertificates); i++) { + if(X509_cmp(cert, sk_X509_value(ctx->trustedCertificates, i)) == 0) + return UA_STATUSCODE_GOOD; + } } return ret; } +/* This follows Part 6, 6.1.3 Determining if a Certificate is trusted. + * It defines a sequence of steps for certificate verification. */ static UA_StatusCode verifyCertificate(UA_CertificateGroup *certGroup, const UA_ByteString *certificate) { /* Check parameter */ @@ -312,149 +499,35 @@ verifyCertificate(UA_CertificateGroup *certGroup, const UA_ByteString *certifica context->reloadRequired = false; } - /* Accept the certificate if the store is empty */ - if(sk_X509_CRL_num(context->crls) == 0 && - sk_X509_num(context->issuerCertificates) == 0 && - sk_X509_num(context->trustedCertificates) == 0) { - UA_LOG_WARNING(certGroup->logging, UA_LOGCATEGORY_USERLAND, - "No certificate store configured. Accepting the certificate."); - return UA_STATUSCODE_GOOD; - } - - X509_STORE_CTX *storeCtx = NULL; - X509_STORE *store = NULL; - UA_StatusCode ret = UA_STATUSCODE_GOOD; - - /* Parse the certificate */ - X509 *certificateX509 = UA_OpenSSL_LoadCertificate(certificate); - if(!certificateX509) { - ret = UA_STATUSCODE_BADCERTIFICATEINVALID; - goto cleanup; - } - - store = X509_STORE_new(); - storeCtx = X509_STORE_CTX_new(); - if(store == NULL || storeCtx == NULL) { - ret = UA_STATUSCODE_BADOUTOFMEMORY; - goto cleanup; + /* Verification Step: Certificate Structure */ + STACK_OF(X509) *stack = openSSLLoadCertificateStack(*certificate); + if(!stack || sk_X509_num(stack) < 1) { + if(stack) + sk_X509_pop_free(stack, X509_free); + return UA_STATUSCODE_BADCERTIFICATEINVALID; } - X509_STORE_set_flags(store, 0); - int opensslRet = X509_STORE_CTX_init(storeCtx, store, certificateX509, - context->issuerCertificates); - if(opensslRet != 1) { - ret = UA_STATUSCODE_BADINTERNALERROR; - goto cleanup; - } -#if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT < 0x10100000L - (void) X509_STORE_CTX_trusted_stack(storeCtx, context->trustedCertificates); -#else - (void) X509_STORE_CTX_set0_trusted_stack(storeCtx, context->trustedCertificates); -#endif - - /* Set crls to ctx */ - if(sk_X509_CRL_num(context->crls) > 0) { - X509_STORE_CTX_set0_crls(storeCtx, context->crls); - } - - /* Set flag to check if the certificate has an invalid signature */ - X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_CHECK_SS_SIGNATURE); - - if(X509_check_issued(certificateX509, certificateX509) != X509_V_OK) { - X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_CRL_CHECK); - } - - /* This condition will check whether the certificate is a User certificate or a CA certificate. - * If the KU_KEY_CERT_SIGN and KU_CRL_SIGN of key_usage are set, then the certificate shall be - * condidered as CA Certificate and cannot be used to establish a connection. Refer the test case - * CTT/Security/Security Certificate Validation/029.js for more details */ - /** \todo Can the ca-parameter of X509_check_purpose can be used? */ - if(X509_check_purpose(certificateX509, X509_PURPOSE_CRL_SIGN, 0) && X509_check_ca(certificateX509)) { + /* Verification Step: Certificate Usage + * Check whether the certificate is a User certificate or a CA certificate. + * Refer the test case CTT/Security/Security Certificate Validation/029.js + * for more details. */ + X509 *leaf = sk_X509_value(stack, 0); + if(X509_check_ca(leaf)) { + sk_X509_pop_free(stack, X509_free); return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED; } - opensslRet = X509_verify_cert(storeCtx); - if(opensslRet == 1) { - ret = UA_STATUSCODE_GOOD; - - /* Check if the not trusted certificate has a CRL file. If there is no CRL file available for the corresponding - * parent certificate then return status code UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN. Refer the test - * case CTT/Security/Security Certificate Validation/002.js */ - if(X509_check_issued(certificateX509, certificateX509) != X509_V_OK) { - /* Free X509_STORE_CTX and reuse it for certification verification */ - if(storeCtx != NULL) { - X509_STORE_CTX_free(storeCtx); - } - - /* Initialised X509_STORE_CTX sructure*/ - storeCtx = X509_STORE_CTX_new(); - - /* Sets up X509_STORE_CTX structure for a subsequent verification operation */ - X509_STORE_set_flags(store, 0); - X509_STORE_CTX_init(storeCtx, store, certificateX509, context->issuerCertificates); - - /* Set trust list to ctx */ - (void) X509_STORE_CTX_trusted_stack(storeCtx, context->trustedCertificates); - - /* Set crls to ctx */ - X509_STORE_CTX_set0_crls(storeCtx, context->crls); - - /* Set flags for CRL check */ - X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - - opensslRet = X509_verify_cert(storeCtx); - if(opensslRet != 1) { - opensslRet = X509_STORE_CTX_get_error(storeCtx); - if(opensslRet == X509_V_ERR_UNABLE_TO_GET_CRL) { - ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN; - } else { - ret = UA_X509_Store_CTX_Error_To_UAError (opensslRet); - } - } - } - } - else { - opensslRet = X509_STORE_CTX_get_error(storeCtx); - - /* Check the issued certificate of a CA that is not trusted but available */ - if(opensslRet == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN){ - int trusted_cert_len = sk_X509_num(context->trustedCertificates); - int cmpVal; - X509 *trusted_cert; - const ASN1_OCTET_STRING *trusted_cert_keyid; - const ASN1_OCTET_STRING *remote_cert_keyid; - - for(int i = 0; i < trusted_cert_len; i++) { - trusted_cert = sk_X509_value(context->trustedCertificates, i); - - /* Fetch the Subject key identifier of the certificate in trust list */ - trusted_cert_keyid = X509_get0_subject_key_id(trusted_cert); - - /* Fetch the Subject key identifier of the remote certificate */ - remote_cert_keyid = X509_get0_subject_key_id(certificateX509); - - if(trusted_cert_keyid && remote_cert_keyid) { - /* Check remote certificate is present in the trust list */ - cmpVal = ASN1_OCTET_STRING_cmp(trusted_cert_keyid, remote_cert_keyid); - if(cmpVal == 0) { - ret = UA_STATUSCODE_GOOD; - goto cleanup; - } - } - } - } - - /* Return expected OPCUA error code */ - ret = UA_X509_Store_CTX_Error_To_UAError(opensslRet); - } + /* These steps are performed outside of this method. + * Because we need the server or client context. + * - Security Policy + * - Host Name + * - URI */ -cleanup: - if(store) - X509_STORE_free(store); - if(storeCtx) - X509_STORE_CTX_free(storeCtx); - if(certificateX509) - X509_free(certificateX509); + /* Verification Step: Build Certificate Chain + * We perform the checks for each certificate inside. */ + X509 *old_issuers[UA_OPENSSL_MAX_CHAIN_LENGTH]; + UA_StatusCode ret = openSSL_verifyChain(context, stack, old_issuers, leaf, 0); + sk_X509_pop_free(stack, X509_free); return ret; } @@ -467,10 +540,7 @@ MemoryCertStore_verifyCertificate(UA_CertificateGroup *certGroup, } UA_StatusCode retval = verifyCertificate(certGroup, certificate); - if(retval == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED || - retval == UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED || - retval == UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN || - retval == UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN) { + if(retval != UA_STATUSCODE_GOOD) { if(MemoryCertStore_addToRejectedList(certGroup, certificate) != UA_STATUSCODE_GOOD) { UA_LOG_WARNING(certGroup->logging, UA_LOGCATEGORY_SECURITYPOLICY, "Could not append certificate to rejected list"); @@ -546,45 +616,6 @@ UA_CertificateGroup_Memorystore(UA_CertificateGroup *certGroup, return retval; } -/* Find binary substring. Taken and adjusted from - * http://tungchingkai.blogspot.com/2011/07/binary-strstr.html */ - -static const unsigned char * -bstrchr(const unsigned char *s, const unsigned char ch, size_t l) { - /* find first occurrence of c in char s[] for length l*/ - for(; l > 0; ++s, --l) { - if(*s == ch) - return s; - } - return NULL; -} - -static const unsigned char * -UA_Bstrstr(const unsigned char *s1, size_t l1, const unsigned char *s2, size_t l2) { - /* find first occurrence of s2[] in s1[] for length l1*/ - const unsigned char *ss1 = s1; - const unsigned char *ss2 = s2; - /* handle special case */ - if(l1 == 0) - return (NULL); - if(l2 == 0) - return s1; - - /* match prefix */ - for (; (s1 = bstrchr(s1, *s2, (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1)) != NULL && - (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1 != 0; ++s1) { - - /* match rest of prefix */ - const unsigned char *sc1, *sc2; - for (sc1 = s1, sc2 = s2; ;) - if (++sc2 >= ss2+l2) - return s1; - else if (*++sc1 != *sc2) - break; - } - return NULL; -} - UA_StatusCode UA_CertificateUtils_verifyApplicationURI(UA_RuleHandling ruleHandling, const UA_ByteString *certificate, diff --git a/plugins/ua_config_default.c b/plugins/ua_config_default.c index 12fdea0b110..080e149de68 100644 --- a/plugins/ua_config_default.c +++ b/plugins/ua_config_default.c @@ -432,7 +432,12 @@ setDefaultConfig(UA_ServerConfig *conf, UA_UInt16 portNumber) { /* Certificate Verification that accepts every certificate. Can be * overwritten when the policy is specialized. */ + if(conf->secureChannelPKI.clear) + conf->secureChannelPKI.clear(&conf->secureChannelPKI); UA_CertificateGroup_AcceptAll(&conf->secureChannelPKI); + + if(conf->sessionPKI.clear) + conf->sessionPKI.clear(&conf->sessionPKI); UA_CertificateGroup_AcceptAll(&conf->sessionPKI); /* * Global Node Lifecycle * */ @@ -1017,6 +1022,8 @@ UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf, paramsMap.map = params; paramsMap.mapSize = paramsSize; + if(conf->secureChannelPKI.clear) + conf->secureChannelPKI.clear(&conf->secureChannelPKI); UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); retval = UA_CertificateGroup_Memorystore(&conf->secureChannelPKI, &defaultApplicationGroup, &list, conf->logging, ¶msMap); @@ -1025,6 +1032,8 @@ UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf, return retval; } + if(conf->sessionPKI.clear) + conf->sessionPKI.clear(&conf->sessionPKI); UA_NodeId defaultUserTokenGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP); retval = UA_CertificateGroup_Memorystore(&conf->sessionPKI, &defaultUserTokenGroup, &list, conf->logging, ¶msMap); @@ -1631,6 +1640,8 @@ UA_ClientConfig_setDefaultEncryption(UA_ClientConfig *config, paramsMap.map = params; paramsMap.mapSize = paramsSize; + if(config->certificateVerification.clear) + config->certificateVerification.clear(&config->certificateVerification); UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); retval = UA_CertificateGroup_Memorystore(&config->certificateVerification, &defaultApplicationGroup, &list, config->logging, ¶msMap); diff --git a/src/client/ua_client_connect.c b/src/client/ua_client_connect.c index aea4463aa55..381b961e9a8 100644 --- a/src/client/ua_client_connect.c +++ b/src/client/ua_client_connect.c @@ -196,7 +196,7 @@ signActivateSessionRequest(UA_Client *client, UA_SecureChannel *channel, UA_ByteString signData = UA_BYTESTRING_NULL; size_t signDataSize = channel->remoteCertificate.length + client->serverSessionNonce.length; - if(dataToSignSize > MAX_DATA_SIZE) { + if(signDataSize > MAX_DATA_SIZE) { retval = UA_STATUSCODE_BADINTERNALERROR; goto cleanup; } diff --git a/src/pubsub/ua_pubsub.h b/src/pubsub/ua_pubsub.h index 0870aa43f8f..47d54479016 100644 --- a/src/pubsub/ua_pubsub.h +++ b/src/pubsub/ua_pubsub.h @@ -260,6 +260,8 @@ typedef struct UA_PubSubConnection { size_t readerGroupsSize; LIST_HEAD(, UA_ReaderGroup) readerGroups; + UA_DateTime silenceErrorUntil; /* Avoid generating too many logs */ + UA_Boolean deleteFlag; /* To be deleted - in addition to the PubSubState */ UA_DelayedCallback dc; /* For delayed freeing */ } UA_PubSubConnection; diff --git a/src/pubsub/ua_pubsub_connection.c b/src/pubsub/ua_pubsub_connection.c index 05524cd0e61..a5d0ee797c5 100644 --- a/src/pubsub/ua_pubsub_connection.c +++ b/src/pubsub/ua_pubsub_connection.c @@ -79,9 +79,13 @@ UA_PubSubConnection_decodeNetworkMessage(UA_PubSubManager *psm, loops_exit: if(!processed) { - UA_LOG_WARNING_PUBSUB(psm->logging, connection, - "Could not decode the received NetworkMessage " - "-- No matching ReaderGroup"); + UA_DateTime nowM = UA_DateTime_nowMonotonic(); + if(connection->silenceErrorUntil < nowM) { + UA_LOG_WARNING_PUBSUB(psm->logging, connection, + "Could not decode the received NetworkMessage " + "-- No matching ReaderGroup"); + connection->silenceErrorUntil = nowM + (UA_DateTime)(10.0 * UA_DATETIME_SEC); + } UA_NetworkMessage_clear(nm); return UA_STATUSCODE_BADINTERNALERROR; } @@ -284,7 +288,7 @@ UA_PubSubConnection_process(UA_PubSubManager *psm, UA_PubSubConnection *c, if(rg->head.state != UA_PUBSUBSTATE_OPERATIONAL && rg->head.state != UA_PUBSUBSTATE_PREOPERATIONAL) continue; - if(rg->config.rtLevel != UA_PUBSUB_RT_FIXED_SIZE) { + if(!(rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE)) { nonRtRg = rg; continue; } @@ -323,7 +327,7 @@ UA_PubSubConnection_process(UA_PubSubManager *psm, UA_PubSubConnection *c, if(rg->head.state != UA_PUBSUBSTATE_OPERATIONAL && rg->head.state != UA_PUBSUBSTATE_PREOPERATIONAL) continue; - if(rg->config.rtLevel == UA_PUBSUB_RT_FIXED_SIZE) + if(rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) continue; processed |= UA_ReaderGroup_process(psm, rg, &nm); } @@ -331,9 +335,13 @@ UA_PubSubConnection_process(UA_PubSubManager *psm, UA_PubSubConnection *c, finish: if(!processed) { - UA_LOG_WARNING_PUBSUB(psm->logging, c, - "Message received that could not be processed. " - "Check PublisherID, WriterGroupID and DatasetWriterID."); + UA_DateTime nowM = UA_DateTime_nowMonotonic(); + if(c->silenceErrorUntil < nowM) { + UA_LOG_WARNING_PUBSUB(psm->logging, c, + "Message received that could not be processed. " + "Check PublisherID, WriterGroupID and DatasetWriterID."); + c->silenceErrorUntil = nowM + (UA_DateTime)(10.0 * UA_DATETIME_SEC); + } } } diff --git a/src/pubsub/ua_pubsub_dataset.c b/src/pubsub/ua_pubsub_dataset.c index 6c20ebb8677..ba06065294d 100644 --- a/src/pubsub/ua_pubsub_dataset.c +++ b/src/pubsub/ua_pubsub_dataset.c @@ -581,8 +581,6 @@ UA_PublishedDataSet_create(UA_PubSubManager *psm, UA_PubSubConfigurationVersionTimeDifference(el->dateTime_now(el)); switch(newConfig->publishedDataSetType) { case UA_PUBSUB_DATASET_PUBLISHEDEVENTS_TEMPLATE: - res = UA_STATUSCODE_BADNOTSUPPORTED; - break; case UA_PUBSUB_DATASET_PUBLISHEDEVENTS: res = UA_STATUSCODE_BADNOTSUPPORTED; break; diff --git a/src/pubsub/ua_pubsub_reader.c b/src/pubsub/ua_pubsub_reader.c index e3e9927ca48..27ccc0bc3dc 100644 --- a/src/pubsub/ua_pubsub_reader.c +++ b/src/pubsub/ua_pubsub_reader.c @@ -536,7 +536,7 @@ DataSetReader_processRaw(UA_PubSubManager *psm, UA_DataSetReader *dsr, } /* Write the value */ - if(tv->beforeWrite || tv->externalDataValue) { + if(tv->externalDataValue) { if(tv->beforeWrite) tv->beforeWrite(psm->sc.server, &dsr->head.identifier, &dsr->linkedReaderGroup->head.identifier, diff --git a/src/pubsub/ua_pubsub_writer.c b/src/pubsub/ua_pubsub_writer.c index eac127fc308..6ba4b1b8e57 100644 --- a/src/pubsub/ua_pubsub_writer.c +++ b/src/pubsub/ua_pubsub_writer.c @@ -728,23 +728,16 @@ UA_DataSetWriter_generateDataSetMessage(UA_PubSubManager *psm, if((u64)jsonDsm->dataSetMessageContentMask & (u64)UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION) { dataSetMessage->header.configVersionMajorVersionEnabled = true; - if(!pds) { - /* Heartbeat */ - dataSetMessage->header.configVersionMajorVersion = 0; - } else { - dataSetMessage->header.configVersionMajorVersion = - pds->dataSetMetaData.configurationVersion.majorVersion; - } - } - if((u64)jsonDsm->dataSetMessageContentMask & - (u64)UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION) { dataSetMessage->header.configVersionMinorVersionEnabled = true; if(!pds) { /* Heartbeat */ + dataSetMessage->header.configVersionMajorVersion = 0; dataSetMessage->header.configVersionMinorVersion = 0; } else { + dataSetMessage->header.configVersionMajorVersion = + pds->dataSetMetaData.configurationVersion.majorVersion; dataSetMessage->header.configVersionMinorVersion = - pds->dataSetMetaData.configurationVersion.minorVersion; + pds->dataSetMetaData.configurationVersion.minorVersion; } } diff --git a/src/server/ua_server_utils.c b/src/server/ua_server_utils.c index d8f5146c097..d79ca864b4c 100644 --- a/src/server/ua_server_utils.c +++ b/src/server/ua_server_utils.c @@ -36,9 +36,6 @@ getNodeType(UA_Server *server, const UA_NodeHead *head) { UA_Boolean inverse; switch(head->nodeClass) { case UA_NODECLASS_OBJECT: - parentRefIndex = UA_REFERENCETYPEINDEX_HASTYPEDEFINITION; - inverse = false; - break; case UA_NODECLASS_VARIABLE: parentRefIndex = UA_REFERENCETYPEINDEX_HASTYPEDEFINITION; inverse = false; diff --git a/src/server/ua_services_nodemanagement.c b/src/server/ua_services_nodemanagement.c index 2a6da6eb1cb..39815b86105 100644 --- a/src/server/ua_services_nodemanagement.c +++ b/src/server/ua_services_nodemanagement.c @@ -370,10 +370,11 @@ typeCheckVariableNode(UA_Server *server, UA_Session *session, } /* Type-check the value */ - if(retval == UA_STATUSCODE_GOOD && - !compatibleValue(server, session, &node->dataType, node->valueRank, - node->arrayDimensionsSize, node->arrayDimensions, - &value.value, NULL, &reason)) { + UA_Boolean compatible = + compatibleValue(server, session, &node->dataType, + node->valueRank, node->arrayDimensionsSize, + node->arrayDimensions, &value.value, NULL, &reason); + if(!compatible) { UA_LOG_INFO_SESSION(server->config.logging, session, "AddNode (%N): The VariableNode value has " "failed the type check with reason %s. ", @@ -1576,10 +1577,9 @@ addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId) } cleanup: + UA_NODESTORE_RELEASE(server, node); if(type) UA_NODESTORE_RELEASE(server, type); - if(node) - UA_NODESTORE_RELEASE(server, node); if(retval != UA_STATUSCODE_GOOD) deleteNode(server, *nodeId, true); return retval; diff --git a/src/server/ua_subscription.c b/src/server/ua_subscription.c index a0bbc439a04..263b5675b11 100644 --- a/src/server/ua_subscription.c +++ b/src/server/ua_subscription.c @@ -143,9 +143,9 @@ UA_Notification_enqueueAndTrigger(UA_Server *server, UA_Notification *n) { mon->triggeredUntil > nowMonotonic)) { UA_Notification_enqueueSub(n); mon->triggeredUntil = UA_INT64_MIN; - UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, mon->subscription, + UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub, "Notification enqueued (Queue size %lu)", - (long unsigned)mon->subscription->notificationQueueSize); + (long unsigned)sub->notificationQueueSize); } /* Insert into the MonitoredItem. This checks the queue size and diff --git a/src/server/ua_subscription_eventfilter.c b/src/server/ua_subscription_eventfilter.c index 339592ffb92..6e2d4553f91 100644 --- a/src/server/ua_subscription_eventfilter.c +++ b/src/server/ua_subscription_eventfilter.c @@ -29,9 +29,9 @@ static UA_Ternary UA_Ternary_and(UA_Ternary first, UA_Ternary second) { if(first == UA_TERNARY_FALSE || second == UA_TERNARY_FALSE) return UA_TERNARY_FALSE; - if(first == UA_TERNARY_TRUE && second == UA_TERNARY_TRUE) - return UA_TERNARY_TRUE; - return UA_TERNARY_NULL; + if(first == UA_TERNARY_NULL || second == UA_TERNARY_NULL) + return UA_TERNARY_NULL; + return UA_TERNARY_TRUE; } static UA_Ternary @@ -39,7 +39,7 @@ UA_Ternary_or(UA_Ternary first, UA_Ternary second) { if(first == UA_TERNARY_TRUE || second == UA_TERNARY_TRUE) return UA_TERNARY_TRUE; if(first == UA_TERNARY_NULL || second == UA_TERNARY_NULL) - return UA_TERNARY_TRUE; + return UA_TERNARY_NULL; return UA_TERNARY_FALSE; } diff --git a/src/ua_securechannel.c b/src/ua_securechannel.c index f31cd1f30ae..c40713de7a0 100644 --- a/src/ua_securechannel.c +++ b/src/ua_securechannel.c @@ -71,6 +71,7 @@ hideErrors(UA_TcpErrorMessage *const error) { switch(error->error) { case UA_STATUSCODE_BADCERTIFICATEUNTRUSTED: case UA_STATUSCODE_BADCERTIFICATEREVOKED: + case UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED: error->error = UA_STATUSCODE_BADSECURITYCHECKSFAILED; error->reason = UA_STRING_NULL; break; diff --git a/src/ua_types.c b/src/ua_types.c index 8e403d16334..39bc7ee2a1c 100644 --- a/src/ua_types.c +++ b/src/ua_types.c @@ -1638,7 +1638,7 @@ extensionObjectOrder(const UA_ExtensionObject *p1, const UA_ExtensionObject *p2, case UA_EXTENSIONOBJECT_DECODED: default: { const UA_DataType *type1 = p1->content.decoded.type; - const UA_DataType *type2 = p1->content.decoded.type; + const UA_DataType *type2 = p2->content.decoded.type; if(type1 != type2) return ((uintptr_t)type1 < (uintptr_t)type2) ? UA_ORDER_LESS : UA_ORDER_MORE; if(!type1) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 518bc7a6449..f32089831d7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -349,6 +349,7 @@ endif() if(UA_ENABLE_ENCRYPTION) ua_add_test(client/check_client_encryption.c) + ua_add_test(encryption/check_crl_validation.c) if(UA_ENABLE_ENCRYPTION_OPENSSL OR UA_ENABLE_ENCRYPTION_MBEDTLS) ua_add_test(client/check_client_authentication.c) diff --git a/tests/encryption/certificates.h b/tests/encryption/certificates.h index da843bb9932..75089746058 100644 --- a/tests/encryption/certificates.h +++ b/tests/encryption/certificates.h @@ -470,6 +470,784 @@ UA_Byte KEY_PEM_PASSWORD_DATA[KEY_PEM_PASSWORD_LENGTH] = { 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; +#define ROOT_CERT_DER_LENGTH 2000 +UA_Byte ROOT_CERT_DER_DATA[2000] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, + 0x6d, 0x54, 0x43, 0x43, 0x41, 0x34, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x44, 0x4f, 0x39, 0x78, 0x48, 0x76, 0x72, 0x67, 0x31, 0x4d, 0x48, 0x57, 0x74, 0x4e, 0x7a, 0x4c, + 0x49, 0x73, 0x30, 0x39, 0x35, 0x67, 0x58, 0x6b, 0x6d, 0x69, 0x4d, 0x77, 0x44, 0x51, 0x59, 0x4a, + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x5a, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, + 0x43, 0x52, 0x45, 0x55, 0x78, 0x44, 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, + 0x4d, 0x42, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, + 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x52, 0x44, 0x61, 0x58, 0x52, 0x35, 0x0a, 0x4d, 0x52, + 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x78, 0x50, 0x63, 0x6d, + 0x64, 0x68, 0x62, 0x6d, 0x6c, 0x36, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x45, 0x44, + 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x4d, 0x42, 0x30, 0x39, 0x79, 0x5a, 0x31, + 0x56, 0x75, 0x61, 0x58, 0x51, 0x78, 0x44, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, + 0x41, 0x4d, 0x4d, 0x42, 0x6c, 0x4a, 0x76, 0x62, 0x33, 0x52, 0x44, 0x51, 0x54, 0x41, 0x65, 0x46, + 0x77, 0x30, 0x79, 0x4e, 0x44, 0x41, 0x35, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x54, 0x55, 0x31, 0x4e, + 0x44, 0x64, 0x61, 0x46, 0x77, 0x30, 0x7a, 0x4e, 0x44, 0x41, 0x35, 0x4d, 0x44, 0x6b, 0x78, 0x4d, + 0x54, 0x55, 0x31, 0x4e, 0x44, 0x64, 0x61, 0x4d, 0x47, 0x59, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x0a, + 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6b, 0x52, 0x46, 0x4d, 0x51, 0x34, 0x77, + 0x44, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x56, 0x54, 0x64, 0x47, 0x46, 0x30, + 0x5a, 0x54, 0x45, 0x4e, 0x4d, 0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x45, + 0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, + 0x0a, 0x43, 0x67, 0x77, 0x4d, 0x54, 0x33, 0x4a, 0x6e, 0x59, 0x57, 0x35, 0x70, 0x65, 0x6d, 0x46, + 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, + 0x4c, 0x44, 0x41, 0x64, 0x50, 0x63, 0x6d, 0x64, 0x56, 0x62, 0x6d, 0x6c, 0x30, 0x4d, 0x51, 0x38, + 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x41, 0x5a, 0x53, 0x62, 0x32, 0x39, + 0x30, 0x0a, 0x51, 0x30, 0x45, 0x77, 0x67, 0x67, 0x49, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, + 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, + 0x49, 0x43, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x49, 0x4b, 0x41, 0x6f, 0x49, 0x43, 0x41, 0x51, + 0x44, 0x4f, 0x78, 0x50, 0x54, 0x36, 0x4b, 0x6d, 0x52, 0x4e, 0x34, 0x51, 0x67, 0x4e, 0x55, 0x61, + 0x37, 0x54, 0x0a, 0x59, 0x2f, 0x56, 0x5a, 0x76, 0x68, 0x58, 0x6e, 0x53, 0x35, 0x75, 0x2f, 0x5a, + 0x47, 0x73, 0x37, 0x6d, 0x47, 0x37, 0x53, 0x4d, 0x6f, 0x50, 0x6f, 0x71, 0x49, 0x44, 0x44, 0x7a, + 0x4d, 0x74, 0x44, 0x57, 0x32, 0x66, 0x51, 0x78, 0x62, 0x34, 0x36, 0x48, 0x43, 0x76, 0x63, 0x38, + 0x55, 0x4f, 0x68, 0x38, 0x2f, 0x37, 0x34, 0x70, 0x50, 0x59, 0x48, 0x4c, 0x41, 0x34, 0x59, 0x58, + 0x67, 0x58, 0x37, 0x0a, 0x36, 0x49, 0x6f, 0x34, 0x6a, 0x52, 0x6b, 0x79, 0x6e, 0x6d, 0x50, 0x7a, + 0x44, 0x66, 0x43, 0x31, 0x37, 0x43, 0x56, 0x4c, 0x53, 0x63, 0x64, 0x42, 0x58, 0x35, 0x51, 0x48, + 0x57, 0x43, 0x6c, 0x5a, 0x56, 0x48, 0x43, 0x58, 0x77, 0x4c, 0x75, 0x42, 0x45, 0x59, 0x49, 0x47, + 0x6f, 0x30, 0x78, 0x33, 0x65, 0x66, 0x75, 0x39, 0x6c, 0x75, 0x69, 0x73, 0x70, 0x70, 0x73, 0x4c, + 0x7a, 0x59, 0x54, 0x4d, 0x0a, 0x38, 0x31, 0x62, 0x79, 0x6a, 0x2b, 0x78, 0x74, 0x49, 0x64, 0x42, + 0x72, 0x68, 0x4c, 0x68, 0x39, 0x48, 0x5a, 0x4f, 0x73, 0x57, 0x6b, 0x63, 0x70, 0x79, 0x68, 0x38, + 0x75, 0x52, 0x55, 0x6d, 0x35, 0x43, 0x50, 0x76, 0x2f, 0x74, 0x78, 0x4f, 0x36, 0x4f, 0x6a, 0x6e, + 0x41, 0x67, 0x4f, 0x2b, 0x47, 0x33, 0x38, 0x38, 0x56, 0x71, 0x55, 0x4b, 0x59, 0x38, 0x76, 0x54, + 0x46, 0x54, 0x30, 0x49, 0x61, 0x0a, 0x76, 0x36, 0x4d, 0x36, 0x6b, 0x62, 0x57, 0x45, 0x78, 0x49, + 0x50, 0x5a, 0x52, 0x62, 0x6d, 0x51, 0x52, 0x64, 0x74, 0x5a, 0x74, 0x59, 0x57, 0x72, 0x54, 0x43, + 0x2f, 0x50, 0x54, 0x43, 0x45, 0x6b, 0x73, 0x34, 0x61, 0x76, 0x6e, 0x47, 0x38, 0x44, 0x61, 0x52, + 0x4f, 0x39, 0x66, 0x42, 0x6c, 0x79, 0x65, 0x37, 0x61, 0x32, 0x45, 0x6f, 0x62, 0x35, 0x33, 0x34, + 0x42, 0x76, 0x4d, 0x2f, 0x74, 0x76, 0x0a, 0x30, 0x74, 0x63, 0x6f, 0x38, 0x2b, 0x50, 0x69, 0x58, + 0x52, 0x70, 0x61, 0x6a, 0x66, 0x71, 0x56, 0x68, 0x31, 0x43, 0x70, 0x61, 0x68, 0x7a, 0x7a, 0x78, + 0x5a, 0x35, 0x65, 0x76, 0x4d, 0x7a, 0x77, 0x78, 0x4d, 0x43, 0x2f, 0x74, 0x75, 0x61, 0x69, 0x54, + 0x76, 0x76, 0x4d, 0x56, 0x44, 0x62, 0x33, 0x63, 0x68, 0x53, 0x77, 0x41, 0x4a, 0x55, 0x6c, 0x75, + 0x33, 0x48, 0x73, 0x59, 0x35, 0x5a, 0x4d, 0x0a, 0x72, 0x52, 0x59, 0x31, 0x6b, 0x56, 0x30, 0x4a, + 0x74, 0x4f, 0x35, 0x68, 0x64, 0x58, 0x44, 0x57, 0x61, 0x79, 0x35, 0x59, 0x52, 0x78, 0x75, 0x42, + 0x2f, 0x76, 0x45, 0x65, 0x2f, 0x36, 0x77, 0x2b, 0x4b, 0x4e, 0x42, 0x35, 0x75, 0x4e, 0x62, 0x73, + 0x55, 0x78, 0x6f, 0x6a, 0x35, 0x79, 0x48, 0x44, 0x6b, 0x45, 0x67, 0x75, 0x42, 0x4b, 0x4a, 0x38, + 0x59, 0x77, 0x42, 0x36, 0x44, 0x47, 0x4e, 0x31, 0x0a, 0x32, 0x53, 0x57, 0x57, 0x5a, 0x45, 0x47, + 0x34, 0x38, 0x4b, 0x67, 0x30, 0x6e, 0x52, 0x68, 0x6b, 0x54, 0x35, 0x6d, 0x62, 0x45, 0x44, 0x45, + 0x68, 0x49, 0x57, 0x43, 0x2f, 0x61, 0x30, 0x50, 0x6e, 0x73, 0x6a, 0x49, 0x71, 0x69, 0x49, 0x68, + 0x6a, 0x5a, 0x6a, 0x61, 0x77, 0x35, 0x6f, 0x62, 0x74, 0x30, 0x38, 0x71, 0x58, 0x2b, 0x63, 0x79, + 0x67, 0x32, 0x52, 0x31, 0x4e, 0x66, 0x51, 0x77, 0x7a, 0x0a, 0x74, 0x35, 0x33, 0x68, 0x79, 0x47, + 0x6c, 0x48, 0x65, 0x35, 0x4e, 0x35, 0x61, 0x61, 0x7a, 0x77, 0x57, 0x4b, 0x4a, 0x42, 0x73, 0x72, + 0x78, 0x48, 0x50, 0x74, 0x77, 0x38, 0x79, 0x48, 0x56, 0x64, 0x4a, 0x64, 0x73, 0x66, 0x59, 0x6c, + 0x38, 0x70, 0x7a, 0x39, 0x63, 0x34, 0x76, 0x54, 0x50, 0x59, 0x6e, 0x5a, 0x33, 0x4d, 0x41, 0x41, + 0x46, 0x59, 0x44, 0x76, 0x57, 0x70, 0x33, 0x45, 0x52, 0x44, 0x0a, 0x30, 0x70, 0x48, 0x48, 0x57, + 0x6d, 0x67, 0x30, 0x73, 0x6c, 0x76, 0x41, 0x66, 0x4f, 0x6e, 0x6f, 0x35, 0x31, 0x55, 0x41, 0x32, + 0x53, 0x65, 0x77, 0x2b, 0x51, 0x52, 0x37, 0x53, 0x53, 0x30, 0x33, 0x70, 0x49, 0x55, 0x69, 0x58, + 0x53, 0x68, 0x75, 0x2b, 0x38, 0x51, 0x56, 0x66, 0x6b, 0x6f, 0x6b, 0x66, 0x4a, 0x66, 0x67, 0x71, + 0x30, 0x4f, 0x45, 0x30, 0x33, 0x31, 0x78, 0x46, 0x77, 0x66, 0x41, 0x0a, 0x5a, 0x46, 0x68, 0x39, + 0x53, 0x49, 0x4b, 0x48, 0x38, 0x51, 0x31, 0x32, 0x47, 0x55, 0x61, 0x6c, 0x34, 0x53, 0x55, 0x73, + 0x65, 0x4d, 0x4d, 0x43, 0x34, 0x73, 0x76, 0x55, 0x4f, 0x48, 0x4d, 0x36, 0x6d, 0x58, 0x2b, 0x32, + 0x4f, 0x64, 0x5a, 0x33, 0x64, 0x32, 0x77, 0x79, 0x4c, 0x77, 0x55, 0x34, 0x43, 0x37, 0x6a, 0x2b, + 0x32, 0x6e, 0x71, 0x51, 0x66, 0x53, 0x39, 0x45, 0x4f, 0x63, 0x65, 0x66, 0x0a, 0x42, 0x58, 0x76, + 0x53, 0x4e, 0x59, 0x33, 0x71, 0x2f, 0x36, 0x61, 0x34, 0x37, 0x48, 0x49, 0x47, 0x5a, 0x4d, 0x62, + 0x6b, 0x4a, 0x75, 0x35, 0x7a, 0x65, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x7a, 0x38, + 0x77, 0x50, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, + 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x41, 0x73, 0x47, 0x0a, 0x41, 0x31, + 0x55, 0x64, 0x44, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, 0x64, 0x42, 0x67, + 0x4e, 0x56, 0x48, 0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x30, 0x6c, 0x76, 0x57, 0x4b, 0x57, + 0x53, 0x77, 0x72, 0x4c, 0x51, 0x74, 0x44, 0x30, 0x2f, 0x64, 0x76, 0x57, 0x56, 0x5a, 0x67, 0x73, + 0x64, 0x42, 0x39, 0x43, 0x59, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x0a, 0x68, + 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, + 0x42, 0x44, 0x44, 0x68, 0x4b, 0x76, 0x57, 0x30, 0x73, 0x55, 0x70, 0x64, 0x75, 0x49, 0x47, 0x74, + 0x68, 0x4e, 0x34, 0x6f, 0x38, 0x62, 0x37, 0x61, 0x45, 0x41, 0x6e, 0x4e, 0x77, 0x2f, 0x2b, 0x62, + 0x61, 0x5a, 0x30, 0x54, 0x38, 0x32, 0x6e, 0x59, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x50, 0x76, 0x0a, + 0x42, 0x76, 0x30, 0x4e, 0x48, 0x50, 0x6a, 0x53, 0x5a, 0x37, 0x33, 0x4d, 0x43, 0x56, 0x6c, 0x4d, + 0x61, 0x2b, 0x66, 0x39, 0x65, 0x62, 0x71, 0x65, 0x73, 0x54, 0x49, 0x45, 0x77, 0x47, 0x41, 0x65, + 0x78, 0x4a, 0x45, 0x39, 0x76, 0x4b, 0x49, 0x5a, 0x68, 0x31, 0x30, 0x53, 0x70, 0x79, 0x78, 0x61, + 0x62, 0x77, 0x68, 0x56, 0x6f, 0x47, 0x41, 0x71, 0x30, 0x74, 0x44, 0x51, 0x68, 0x7a, 0x47, 0x77, + 0x0a, 0x71, 0x6d, 0x34, 0x4d, 0x30, 0x34, 0x4c, 0x62, 0x33, 0x53, 0x46, 0x42, 0x75, 0x76, 0x52, + 0x70, 0x46, 0x34, 0x6f, 0x68, 0x62, 0x4d, 0x51, 0x64, 0x47, 0x49, 0x76, 0x71, 0x2b, 0x75, 0x34, + 0x72, 0x6d, 0x6d, 0x39, 0x54, 0x62, 0x69, 0x70, 0x41, 0x63, 0x43, 0x33, 0x47, 0x37, 0x50, 0x32, + 0x6a, 0x4c, 0x42, 0x53, 0x38, 0x37, 0x55, 0x48, 0x7a, 0x32, 0x74, 0x71, 0x42, 0x74, 0x4b, 0x64, + 0x4d, 0x0a, 0x64, 0x39, 0x44, 0x47, 0x73, 0x78, 0x78, 0x7a, 0x6b, 0x50, 0x75, 0x4c, 0x77, 0x48, + 0x50, 0x52, 0x36, 0x58, 0x75, 0x77, 0x75, 0x30, 0x78, 0x35, 0x5a, 0x38, 0x37, 0x4f, 0x58, 0x6e, + 0x6e, 0x6e, 0x6a, 0x38, 0x75, 0x59, 0x77, 0x61, 0x31, 0x2b, 0x55, 0x56, 0x6f, 0x65, 0x59, 0x7a, + 0x4a, 0x4c, 0x30, 0x75, 0x31, 0x51, 0x38, 0x46, 0x2f, 0x6c, 0x47, 0x63, 0x7a, 0x39, 0x65, 0x57, + 0x44, 0x6d, 0x0a, 0x6e, 0x58, 0x78, 0x75, 0x36, 0x64, 0x35, 0x79, 0x68, 0x70, 0x6c, 0x64, 0x4a, + 0x6f, 0x2b, 0x67, 0x42, 0x71, 0x72, 0x4d, 0x58, 0x6c, 0x32, 0x58, 0x4e, 0x4e, 0x5a, 0x61, 0x39, + 0x6e, 0x4d, 0x4a, 0x52, 0x54, 0x64, 0x2b, 0x6f, 0x57, 0x69, 0x54, 0x47, 0x65, 0x4e, 0x74, 0x4e, + 0x48, 0x6f, 0x41, 0x44, 0x7a, 0x34, 0x30, 0x2b, 0x41, 0x64, 0x62, 0x69, 0x47, 0x35, 0x48, 0x35, + 0x35, 0x30, 0x77, 0x0a, 0x4d, 0x45, 0x54, 0x57, 0x64, 0x54, 0x4e, 0x63, 0x4d, 0x6d, 0x4c, 0x31, + 0x77, 0x57, 0x6a, 0x30, 0x67, 0x35, 0x35, 0x49, 0x57, 0x7a, 0x65, 0x65, 0x48, 0x68, 0x73, 0x4e, + 0x54, 0x75, 0x66, 0x46, 0x55, 0x70, 0x48, 0x44, 0x4d, 0x34, 0x33, 0x61, 0x2f, 0x33, 0x7a, 0x53, + 0x48, 0x6e, 0x41, 0x44, 0x6f, 0x75, 0x5a, 0x78, 0x6e, 0x53, 0x67, 0x72, 0x71, 0x30, 0x31, 0x76, + 0x55, 0x75, 0x69, 0x70, 0x0a, 0x31, 0x6b, 0x45, 0x72, 0x35, 0x65, 0x53, 0x59, 0x64, 0x47, 0x6f, + 0x64, 0x34, 0x36, 0x78, 0x58, 0x35, 0x30, 0x56, 0x56, 0x4c, 0x79, 0x61, 0x53, 0x72, 0x39, 0x2b, + 0x37, 0x71, 0x4a, 0x64, 0x75, 0x77, 0x2b, 0x7a, 0x73, 0x41, 0x6d, 0x67, 0x50, 0x55, 0x58, 0x65, + 0x58, 0x7a, 0x79, 0x31, 0x7a, 0x44, 0x34, 0x46, 0x47, 0x61, 0x54, 0x2f, 0x56, 0x62, 0x57, 0x63, + 0x70, 0x37, 0x76, 0x65, 0x4c, 0x0a, 0x56, 0x48, 0x58, 0x53, 0x38, 0x35, 0x6b, 0x72, 0x72, 0x5a, + 0x6c, 0x4f, 0x64, 0x6c, 0x4b, 0x56, 0x4a, 0x6d, 0x45, 0x78, 0x4a, 0x45, 0x30, 0x6e, 0x4c, 0x4d, + 0x6b, 0x38, 0x55, 0x50, 0x53, 0x63, 0x75, 0x46, 0x35, 0x4c, 0x48, 0x36, 0x69, 0x61, 0x39, 0x51, + 0x67, 0x41, 0x53, 0x34, 0x6d, 0x35, 0x43, 0x66, 0x55, 0x33, 0x76, 0x69, 0x35, 0x77, 0x6d, 0x37, + 0x71, 0x6e, 0x59, 0x56, 0x77, 0x37, 0x0a, 0x45, 0x55, 0x4e, 0x50, 0x39, 0x36, 0x72, 0x78, 0x31, + 0x44, 0x66, 0x64, 0x2f, 0x41, 0x58, 0x73, 0x6a, 0x4a, 0x44, 0x62, 0x50, 0x6e, 0x4a, 0x57, 0x53, + 0x45, 0x69, 0x73, 0x4e, 0x35, 0x63, 0x31, 0x64, 0x67, 0x30, 0x56, 0x74, 0x48, 0x51, 0x56, 0x70, + 0x33, 0x67, 0x77, 0x39, 0x52, 0x56, 0x4e, 0x74, 0x66, 0x6d, 0x2b, 0x59, 0x2b, 0x31, 0x72, 0x33, + 0x2f, 0x44, 0x61, 0x44, 0x42, 0x48, 0x54, 0x0a, 0x49, 0x65, 0x33, 0x30, 0x79, 0x51, 0x50, 0x6c, + 0x41, 0x56, 0x72, 0x56, 0x6a, 0x57, 0x44, 0x77, 0x6e, 0x48, 0x73, 0x35, 0x31, 0x34, 0x50, 0x47, + 0x75, 0x69, 0x4d, 0x42, 0x51, 0x42, 0x67, 0x61, 0x6a, 0x67, 0x6e, 0x64, 0x4f, 0x45, 0x70, 0x54, + 0x67, 0x5a, 0x56, 0x48, 0x2f, 0x46, 0x33, 0x6a, 0x34, 0x59, 0x39, 0x6b, 0x37, 0x36, 0x4c, 0x44, + 0x62, 0x35, 0x45, 0x49, 0x54, 0x68, 0x51, 0x59, 0x0a, 0x59, 0x53, 0x63, 0x33, 0x31, 0x5a, 0x41, + 0x6b, 0x63, 0x49, 0x65, 0x79, 0x53, 0x66, 0x6f, 0x33, 0x2b, 0x51, 0x39, 0x4a, 0x69, 0x78, 0x59, + 0x51, 0x42, 0x78, 0x2f, 0x78, 0x4a, 0x57, 0x34, 0x4d, 0x37, 0x6a, 0x51, 0x33, 0x79, 0x6d, 0x42, + 0x65, 0x58, 0x59, 0x6d, 0x67, 0x66, 0x49, 0x76, 0x2b, 0x2f, 0x51, 0x53, 0x32, 0x59, 0x34, 0x4d, + 0x6d, 0x53, 0x63, 0x6b, 0x50, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, + 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +/* Contains the intermediateCA certificate */ +#define ROOT_CRL_PEM_LENGTH 1109 +UA_Byte ROOT_CRL_PEM_DATA[1109] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, + 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x43, 0x6a, 0x43, + 0x42, 0x38, 0x77, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, + 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x6d, 0x4d, 0x51, 0x73, + 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52, 0x54, 0x45, + 0x4f, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x41, 0x77, 0x46, 0x55, 0x33, + 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x44, 0x54, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, + 0x63, 0x4d, 0x42, 0x45, 0x4e, 0x70, 0x64, 0x48, 0x6b, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x44, 0x45, 0x39, 0x79, 0x5a, 0x32, 0x46, 0x75, 0x61, 0x58, + 0x70, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x48, 0x54, 0x33, 0x4a, 0x6e, 0x56, 0x57, 0x35, 0x70, 0x64, + 0x44, 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x47, 0x55, + 0x6d, 0x39, 0x76, 0x64, 0x45, 0x4e, 0x42, 0x46, 0x77, 0x30, 0x79, 0x4e, 0x44, 0x41, 0x35, 0x4d, + 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x6a, 0x42, 0x61, 0x0a, 0x46, 0x77, 0x30, 0x79, + 0x4e, 0x44, 0x45, 0x77, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x6a, 0x42, 0x61, + 0x4d, 0x43, 0x63, 0x77, 0x4a, 0x51, 0x49, 0x55, 0x54, 0x32, 0x55, 0x75, 0x68, 0x65, 0x71, 0x72, + 0x77, 0x30, 0x34, 0x50, 0x76, 0x54, 0x56, 0x79, 0x32, 0x73, 0x46, 0x44, 0x4e, 0x56, 0x4e, 0x38, + 0x5a, 0x30, 0x63, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x44, 0x6b, 0x78, 0x0a, 0x4d, 0x54, 0x45, + 0x79, 0x4d, 0x44, 0x41, 0x77, 0x4f, 0x56, 0x71, 0x67, 0x4d, 0x44, 0x41, 0x75, 0x4d, 0x42, 0x38, + 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x4e, 0x4a, + 0x62, 0x31, 0x69, 0x6c, 0x6b, 0x73, 0x4b, 0x79, 0x30, 0x4c, 0x51, 0x39, 0x50, 0x33, 0x62, 0x31, + 0x6c, 0x57, 0x59, 0x4c, 0x48, 0x51, 0x66, 0x51, 0x6d, 0x4d, 0x41, 0x73, 0x47, 0x0a, 0x41, 0x31, + 0x55, 0x64, 0x46, 0x41, 0x51, 0x45, 0x41, 0x67, 0x49, 0x51, 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, + 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, + 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x59, 0x30, 0x58, 0x6c, 0x44, 0x31, 0x34, 0x4b, 0x71, 0x32, + 0x51, 0x41, 0x70, 0x77, 0x61, 0x70, 0x68, 0x56, 0x53, 0x58, 0x4b, 0x33, 0x53, 0x39, 0x0a, 0x55, + 0x58, 0x7a, 0x57, 0x41, 0x48, 0x2b, 0x2f, 0x68, 0x39, 0x61, 0x38, 0x46, 0x58, 0x2b, 0x65, 0x45, + 0x61, 0x6f, 0x68, 0x6f, 0x6a, 0x47, 0x51, 0x36, 0x62, 0x57, 0x34, 0x72, 0x68, 0x42, 0x4e, 0x5a, + 0x75, 0x4f, 0x2b, 0x57, 0x31, 0x38, 0x79, 0x78, 0x6b, 0x47, 0x33, 0x2f, 0x61, 0x55, 0x75, 0x68, + 0x30, 0x58, 0x65, 0x77, 0x58, 0x4a, 0x6f, 0x46, 0x67, 0x39, 0x4a, 0x2f, 0x6e, 0x51, 0x6c, 0x0a, + 0x6a, 0x67, 0x5a, 0x70, 0x70, 0x46, 0x6f, 0x54, 0x6b, 0x4a, 0x6d, 0x49, 0x53, 0x64, 0x2f, 0x75, + 0x34, 0x65, 0x70, 0x4b, 0x6b, 0x31, 0x63, 0x4d, 0x2f, 0x71, 0x33, 0x32, 0x6e, 0x42, 0x63, 0x70, + 0x58, 0x7a, 0x6a, 0x6f, 0x5a, 0x33, 0x66, 0x57, 0x6a, 0x43, 0x37, 0x55, 0x5a, 0x4b, 0x62, 0x46, + 0x32, 0x63, 0x31, 0x43, 0x4e, 0x53, 0x61, 0x44, 0x6a, 0x64, 0x35, 0x65, 0x59, 0x2b, 0x36, 0x53, + 0x0a, 0x59, 0x6c, 0x4b, 0x36, 0x45, 0x47, 0x66, 0x6b, 0x57, 0x58, 0x74, 0x66, 0x30, 0x68, 0x50, + 0x46, 0x42, 0x4f, 0x39, 0x69, 0x69, 0x65, 0x32, 0x33, 0x68, 0x41, 0x71, 0x58, 0x4a, 0x6e, 0x67, + 0x46, 0x56, 0x75, 0x67, 0x50, 0x53, 0x39, 0x78, 0x68, 0x38, 0x6d, 0x47, 0x53, 0x64, 0x39, 0x6e, + 0x4d, 0x32, 0x6e, 0x50, 0x68, 0x46, 0x43, 0x49, 0x67, 0x50, 0x6a, 0x37, 0x41, 0x32, 0x73, 0x58, + 0x76, 0x0a, 0x78, 0x79, 0x33, 0x37, 0x36, 0x48, 0x67, 0x6b, 0x2b, 0x66, 0x73, 0x55, 0x59, 0x39, + 0x51, 0x6d, 0x66, 0x42, 0x41, 0x55, 0x46, 0x6e, 0x6c, 0x2b, 0x2b, 0x36, 0x79, 0x6c, 0x54, 0x39, + 0x6c, 0x4d, 0x4e, 0x62, 0x78, 0x2b, 0x50, 0x5a, 0x73, 0x33, 0x30, 0x78, 0x78, 0x64, 0x48, 0x6d, + 0x4f, 0x6f, 0x61, 0x38, 0x69, 0x4a, 0x73, 0x46, 0x56, 0x4a, 0x67, 0x34, 0x71, 0x4c, 0x33, 0x31, + 0x39, 0x6a, 0x0a, 0x55, 0x63, 0x4b, 0x49, 0x67, 0x41, 0x6e, 0x56, 0x48, 0x6e, 0x41, 0x4a, 0x32, + 0x59, 0x42, 0x61, 0x30, 0x4a, 0x30, 0x56, 0x79, 0x38, 0x33, 0x38, 0x30, 0x77, 0x48, 0x64, 0x43, + 0x54, 0x50, 0x5a, 0x32, 0x43, 0x74, 0x77, 0x2f, 0x76, 0x62, 0x74, 0x75, 0x54, 0x56, 0x54, 0x4b, + 0x36, 0x62, 0x44, 0x4b, 0x37, 0x72, 0x76, 0x6a, 0x58, 0x58, 0x4c, 0x34, 0x7a, 0x56, 0x66, 0x71, + 0x7a, 0x32, 0x78, 0x0a, 0x30, 0x63, 0x6e, 0x66, 0x70, 0x64, 0x55, 0x49, 0x57, 0x37, 0x4a, 0x36, + 0x68, 0x64, 0x4e, 0x70, 0x58, 0x77, 0x33, 0x76, 0x4c, 0x67, 0x4c, 0x66, 0x76, 0x57, 0x6b, 0x59, + 0x4b, 0x65, 0x79, 0x35, 0x61, 0x79, 0x72, 0x7a, 0x36, 0x32, 0x37, 0x45, 0x4c, 0x32, 0x47, 0x36, + 0x65, 0x77, 0x51, 0x53, 0x78, 0x71, 0x71, 0x53, 0x4c, 0x73, 0x6b, 0x67, 0x52, 0x52, 0x55, 0x74, + 0x6a, 0x4e, 0x66, 0x79, 0x0a, 0x38, 0x2b, 0x71, 0x34, 0x47, 0x49, 0x32, 0x71, 0x47, 0x4e, 0x71, + 0x4d, 0x48, 0x75, 0x79, 0x32, 0x39, 0x53, 0x70, 0x31, 0x74, 0x4c, 0x78, 0x76, 0x73, 0x71, 0x56, + 0x6e, 0x30, 0x52, 0x55, 0x58, 0x46, 0x42, 0x44, 0x69, 0x62, 0x6c, 0x31, 0x5a, 0x74, 0x67, 0x4f, + 0x65, 0x2b, 0x33, 0x2f, 0x4c, 0x2f, 0x58, 0x7a, 0x6a, 0x76, 0x73, 0x45, 0x78, 0x66, 0x73, 0x77, + 0x4e, 0x54, 0x73, 0x50, 0x4f, 0x0a, 0x2b, 0x54, 0x49, 0x69, 0x42, 0x55, 0x71, 0x5a, 0x4a, 0x4a, + 0x4c, 0x78, 0x61, 0x6d, 0x65, 0x6c, 0x61, 0x69, 0x64, 0x53, 0x45, 0x4d, 0x4e, 0x67, 0x6a, 0x69, + 0x77, 0x75, 0x33, 0x62, 0x45, 0x79, 0x4e, 0x65, 0x6d, 0x63, 0x6b, 0x6c, 0x31, 0x74, 0x70, 0x64, + 0x6a, 0x67, 0x36, 0x2b, 0x79, 0x36, 0x68, 0x56, 0x71, 0x6b, 0x74, 0x76, 0x65, 0x37, 0x4a, 0x42, + 0x33, 0x45, 0x64, 0x67, 0x4f, 0x4c, 0x0a, 0x45, 0x4c, 0x68, 0x7a, 0x50, 0x41, 0x54, 0x38, 0x48, + 0x52, 0x61, 0x75, 0x43, 0x6b, 0x71, 0x47, 0x41, 0x67, 0x61, 0x57, 0x62, 0x58, 0x43, 0x38, 0x31, + 0x65, 0x6d, 0x56, 0x55, 0x52, 0x51, 0x4e, 0x42, 0x71, 0x74, 0x55, 0x30, 0x30, 0x75, 0x77, 0x4a, + 0x45, 0x75, 0x4c, 0x35, 0x73, 0x47, 0x32, 0x4c, 0x4c, 0x53, 0x43, 0x50, 0x2f, 0x78, 0x30, 0x52, + 0x76, 0x46, 0x63, 0x73, 0x32, 0x79, 0x68, 0x0a, 0x73, 0x4a, 0x6f, 0x59, 0x4d, 0x31, 0x61, 0x6f, + 0x6c, 0x43, 0x52, 0x2f, 0x32, 0x52, 0x33, 0x2f, 0x72, 0x2b, 0x57, 0x39, 0x55, 0x52, 0x39, 0x37, + 0x59, 0x72, 0x59, 0x74, 0x75, 0x4a, 0x62, 0x6a, 0x52, 0x42, 0x71, 0x69, 0x56, 0x4d, 0x49, 0x52, + 0x70, 0x53, 0x2f, 0x49, 0x62, 0x49, 0x77, 0x72, 0x50, 0x72, 0x5a, 0x45, 0x47, 0x75, 0x58, 0x67, + 0x35, 0x44, 0x48, 0x56, 0x33, 0x6e, 0x36, 0x63, 0x0a, 0x66, 0x6d, 0x58, 0x2f, 0x76, 0x4b, 0x45, + 0x62, 0x6d, 0x72, 0x74, 0x49, 0x6c, 0x57, 0x6a, 0x45, 0x36, 0x67, 0x49, 0x3d, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, 0x43, 0x52, 0x4c, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +#define ROOT_EMPTY_CRL_PEM_LENGTH 1052 +UA_Byte ROOT_EMPTY_CRL_PEM_DATA[1052] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, + 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x34, 0x54, 0x43, + 0x42, 0x79, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, + 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x6d, 0x4d, 0x51, 0x73, + 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52, 0x54, 0x45, + 0x4f, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x41, 0x77, 0x46, 0x55, 0x33, + 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x44, 0x54, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, + 0x63, 0x4d, 0x42, 0x45, 0x4e, 0x70, 0x64, 0x48, 0x6b, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x44, 0x45, 0x39, 0x79, 0x5a, 0x32, 0x46, 0x75, 0x61, 0x58, + 0x70, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x48, 0x54, 0x33, 0x4a, 0x6e, 0x56, 0x57, 0x35, 0x70, 0x64, + 0x44, 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x47, 0x55, + 0x6d, 0x39, 0x76, 0x64, 0x45, 0x4e, 0x42, 0x46, 0x77, 0x30, 0x79, 0x4e, 0x44, 0x41, 0x35, 0x4d, + 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x41, 0x30, 0x4e, 0x44, 0x56, 0x61, 0x0a, 0x46, 0x77, 0x30, 0x79, + 0x4e, 0x44, 0x45, 0x77, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x41, 0x30, 0x4e, 0x44, 0x56, 0x61, + 0x6f, 0x44, 0x41, 0x77, 0x4c, 0x6a, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, + 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54, 0x53, 0x57, 0x39, 0x59, 0x70, 0x5a, 0x4c, 0x43, 0x73, + 0x74, 0x43, 0x30, 0x50, 0x54, 0x39, 0x32, 0x39, 0x5a, 0x56, 0x6d, 0x43, 0x0a, 0x78, 0x30, 0x48, + 0x30, 0x4a, 0x6a, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x51, 0x45, 0x42, 0x41, 0x49, + 0x43, 0x45, 0x41, 0x4d, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, + 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x42, 0x41, 0x42, 0x59, + 0x65, 0x48, 0x74, 0x57, 0x61, 0x5a, 0x33, 0x6b, 0x4c, 0x46, 0x45, 0x30, 0x63, 0x0a, 0x77, 0x66, + 0x66, 0x42, 0x4b, 0x37, 0x32, 0x62, 0x50, 0x48, 0x6c, 0x6f, 0x34, 0x31, 0x79, 0x2f, 0x6d, 0x48, + 0x38, 0x65, 0x52, 0x63, 0x47, 0x66, 0x57, 0x46, 0x6a, 0x45, 0x6d, 0x50, 0x58, 0x49, 0x67, 0x36, + 0x71, 0x31, 0x44, 0x79, 0x37, 0x66, 0x54, 0x6f, 0x54, 0x69, 0x44, 0x71, 0x72, 0x52, 0x6e, 0x49, + 0x41, 0x68, 0x53, 0x44, 0x6e, 0x4c, 0x6a, 0x56, 0x64, 0x4f, 0x34, 0x74, 0x52, 0x66, 0x0a, 0x73, + 0x6a, 0x64, 0x72, 0x58, 0x2f, 0x32, 0x67, 0x52, 0x30, 0x4e, 0x6f, 0x57, 0x66, 0x48, 0x63, 0x78, + 0x58, 0x61, 0x6b, 0x41, 0x42, 0x4e, 0x31, 0x51, 0x35, 0x45, 0x4e, 0x39, 0x61, 0x4f, 0x74, 0x35, + 0x45, 0x2b, 0x6d, 0x4d, 0x4b, 0x46, 0x59, 0x46, 0x74, 0x4a, 0x55, 0x50, 0x79, 0x76, 0x67, 0x36, + 0x57, 0x63, 0x7a, 0x44, 0x57, 0x52, 0x50, 0x6d, 0x75, 0x32, 0x67, 0x69, 0x44, 0x6c, 0x6d, 0x0a, + 0x31, 0x4c, 0x5a, 0x31, 0x35, 0x56, 0x67, 0x49, 0x77, 0x78, 0x64, 0x55, 0x6d, 0x39, 0x48, 0x35, + 0x32, 0x6e, 0x44, 0x4a, 0x35, 0x54, 0x64, 0x38, 0x4e, 0x4b, 0x6e, 0x53, 0x43, 0x67, 0x58, 0x4b, + 0x62, 0x52, 0x33, 0x47, 0x61, 0x4e, 0x79, 0x66, 0x75, 0x74, 0x73, 0x73, 0x58, 0x72, 0x74, 0x6d, + 0x58, 0x33, 0x42, 0x53, 0x55, 0x78, 0x54, 0x62, 0x6c, 0x5a, 0x48, 0x4e, 0x31, 0x6b, 0x4b, 0x33, + 0x0a, 0x44, 0x52, 0x71, 0x79, 0x74, 0x79, 0x44, 0x52, 0x61, 0x72, 0x4b, 0x49, 0x37, 0x52, 0x58, + 0x52, 0x48, 0x35, 0x46, 0x79, 0x55, 0x32, 0x76, 0x4d, 0x79, 0x49, 0x4c, 0x5a, 0x2b, 0x7a, 0x6b, + 0x45, 0x51, 0x69, 0x75, 0x68, 0x36, 0x62, 0x54, 0x79, 0x43, 0x2b, 0x57, 0x52, 0x37, 0x42, 0x30, + 0x72, 0x44, 0x6a, 0x6f, 0x38, 0x4c, 0x78, 0x72, 0x30, 0x72, 0x72, 0x31, 0x2b, 0x78, 0x59, 0x67, + 0x43, 0x0a, 0x32, 0x4c, 0x50, 0x68, 0x59, 0x63, 0x36, 0x4e, 0x71, 0x6b, 0x6f, 0x76, 0x73, 0x78, + 0x6a, 0x63, 0x33, 0x34, 0x37, 0x72, 0x2f, 0x7a, 0x4e, 0x32, 0x58, 0x45, 0x6d, 0x4b, 0x74, 0x67, + 0x46, 0x44, 0x59, 0x49, 0x71, 0x65, 0x59, 0x5a, 0x47, 0x31, 0x75, 0x4b, 0x36, 0x65, 0x53, 0x59, + 0x4c, 0x32, 0x4d, 0x48, 0x69, 0x32, 0x39, 0x77, 0x33, 0x49, 0x4a, 0x55, 0x4a, 0x64, 0x57, 0x44, + 0x41, 0x4d, 0x0a, 0x48, 0x46, 0x55, 0x64, 0x58, 0x64, 0x77, 0x43, 0x63, 0x2f, 0x62, 0x67, 0x49, + 0x6b, 0x6c, 0x72, 0x35, 0x31, 0x4d, 0x45, 0x69, 0x39, 0x4d, 0x42, 0x70, 0x4a, 0x39, 0x55, 0x43, + 0x77, 0x55, 0x41, 0x68, 0x2b, 0x78, 0x6b, 0x63, 0x42, 0x48, 0x70, 0x4d, 0x76, 0x6f, 0x34, 0x38, + 0x34, 0x75, 0x6c, 0x6f, 0x61, 0x36, 0x6d, 0x77, 0x74, 0x36, 0x32, 0x69, 0x79, 0x57, 0x36, 0x70, + 0x6e, 0x4c, 0x58, 0x0a, 0x78, 0x74, 0x4e, 0x6f, 0x61, 0x53, 0x6a, 0x4b, 0x2b, 0x52, 0x43, 0x4f, + 0x4b, 0x74, 0x57, 0x64, 0x61, 0x7a, 0x70, 0x73, 0x77, 0x36, 0x39, 0x45, 0x44, 0x6d, 0x39, 0x76, + 0x70, 0x4e, 0x32, 0x47, 0x34, 0x4e, 0x52, 0x47, 0x6f, 0x6a, 0x62, 0x4b, 0x59, 0x6a, 0x66, 0x33, + 0x44, 0x6e, 0x2b, 0x6e, 0x43, 0x6d, 0x54, 0x64, 0x36, 0x71, 0x4c, 0x75, 0x41, 0x63, 0x53, 0x62, + 0x4d, 0x31, 0x62, 0x77, 0x0a, 0x4b, 0x43, 0x65, 0x64, 0x70, 0x56, 0x6f, 0x55, 0x6c, 0x6a, 0x72, + 0x43, 0x68, 0x50, 0x62, 0x50, 0x55, 0x39, 0x30, 0x2b, 0x46, 0x50, 0x2b, 0x59, 0x54, 0x33, 0x6e, + 0x6a, 0x51, 0x2f, 0x2b, 0x52, 0x36, 0x68, 0x59, 0x55, 0x78, 0x31, 0x6e, 0x53, 0x62, 0x6c, 0x7a, + 0x37, 0x4f, 0x6d, 0x75, 0x2b, 0x62, 0x2b, 0x57, 0x35, 0x79, 0x71, 0x72, 0x72, 0x69, 0x6f, 0x30, + 0x38, 0x78, 0x50, 0x64, 0x37, 0x0a, 0x2f, 0x51, 0x70, 0x37, 0x32, 0x30, 0x52, 0x35, 0x43, 0x61, + 0x6a, 0x34, 0x4d, 0x70, 0x57, 0x65, 0x44, 0x42, 0x65, 0x78, 0x32, 0x68, 0x41, 0x51, 0x32, 0x39, + 0x44, 0x30, 0x39, 0x70, 0x53, 0x66, 0x5a, 0x35, 0x63, 0x52, 0x32, 0x63, 0x4c, 0x4a, 0x6b, 0x70, + 0x50, 0x53, 0x66, 0x4f, 0x76, 0x62, 0x76, 0x74, 0x4f, 0x56, 0x61, 0x6c, 0x30, 0x6d, 0x36, 0x6c, + 0x34, 0x30, 0x48, 0x4a, 0x52, 0x6c, 0x0a, 0x2f, 0x56, 0x67, 0x2f, 0x63, 0x42, 0x51, 0x67, 0x46, + 0x47, 0x54, 0x39, 0x66, 0x6d, 0x45, 0x4c, 0x36, 0x38, 0x5a, 0x37, 0x48, 0x61, 0x31, 0x76, 0x34, + 0x44, 0x61, 0x7a, 0x47, 0x44, 0x32, 0x2b, 0x71, 0x52, 0x58, 0x69, 0x45, 0x2b, 0x49, 0x5a, 0x53, + 0x55, 0x47, 0x7a, 0x33, 0x4a, 0x4e, 0x7a, 0x59, 0x6d, 0x42, 0x48, 0x75, 0x53, 0x43, 0x51, 0x6d, + 0x39, 0x66, 0x2f, 0x74, 0x69, 0x4a, 0x35, 0x0a, 0x53, 0x51, 0x46, 0x78, 0x6b, 0x47, 0x38, 0x49, + 0x32, 0x45, 0x33, 0x68, 0x73, 0x6c, 0x38, 0x4b, 0x33, 0x65, 0x4d, 0x4d, 0x61, 0x6b, 0x45, 0x43, + 0x66, 0x34, 0x79, 0x53, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x58, 0x35, + 0x30, 0x39, 0x20, 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +#define INTERMEDIATE_CERT_DER_LENGTH 2057 +UA_Byte INTERMEDIATE_CERT_DER_DATA[2057] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, + 0x77, 0x6a, 0x43, 0x43, 0x41, 0x36, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x54, 0x32, 0x55, 0x75, 0x68, 0x65, 0x71, 0x72, 0x77, 0x30, 0x34, 0x50, 0x76, 0x54, 0x56, 0x79, + 0x32, 0x73, 0x46, 0x44, 0x4e, 0x56, 0x4e, 0x38, 0x5a, 0x30, 0x63, 0x77, 0x44, 0x51, 0x59, 0x4a, + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x5a, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, + 0x43, 0x52, 0x45, 0x55, 0x78, 0x44, 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, + 0x4d, 0x42, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, + 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x52, 0x44, 0x61, 0x58, 0x52, 0x35, 0x0a, 0x4d, 0x52, + 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x78, 0x50, 0x63, 0x6d, + 0x64, 0x68, 0x62, 0x6d, 0x6c, 0x36, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x45, 0x44, + 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x4d, 0x42, 0x30, 0x39, 0x79, 0x5a, 0x31, + 0x56, 0x75, 0x61, 0x58, 0x51, 0x78, 0x44, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, + 0x41, 0x4d, 0x4d, 0x42, 0x6c, 0x4a, 0x76, 0x62, 0x33, 0x52, 0x44, 0x51, 0x54, 0x41, 0x65, 0x46, + 0x77, 0x30, 0x79, 0x4e, 0x44, 0x41, 0x35, 0x4d, 0x54, 0x45, 0x78, 0x4d, 0x54, 0x55, 0x33, 0x4d, + 0x7a, 0x5a, 0x61, 0x46, 0x77, 0x30, 0x7a, 0x4e, 0x44, 0x41, 0x35, 0x4d, 0x44, 0x6b, 0x78, 0x4d, + 0x54, 0x55, 0x33, 0x4d, 0x7a, 0x5a, 0x61, 0x4d, 0x47, 0x34, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x0a, + 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6b, 0x52, 0x46, 0x4d, 0x51, 0x34, 0x77, + 0x44, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x56, 0x54, 0x64, 0x47, 0x46, 0x30, + 0x5a, 0x54, 0x45, 0x4e, 0x4d, 0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, 0x77, 0x45, + 0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x56, 0x4d, 0x42, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, + 0x0a, 0x43, 0x67, 0x77, 0x4d, 0x54, 0x33, 0x4a, 0x6e, 0x59, 0x57, 0x35, 0x70, 0x65, 0x6d, 0x46, + 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, + 0x4c, 0x44, 0x41, 0x64, 0x50, 0x63, 0x6d, 0x64, 0x56, 0x62, 0x6d, 0x6c, 0x30, 0x4d, 0x52, 0x63, + 0x77, 0x46, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x41, 0x35, 0x4a, 0x62, 0x6e, 0x52, + 0x6c, 0x0a, 0x63, 0x6d, 0x31, 0x6c, 0x5a, 0x47, 0x6c, 0x68, 0x64, 0x47, 0x56, 0x44, 0x51, 0x54, + 0x43, 0x43, 0x41, 0x69, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, + 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, 0x49, 0x50, 0x41, 0x44, + 0x43, 0x43, 0x41, 0x67, 0x6f, 0x43, 0x67, 0x67, 0x49, 0x42, 0x41, 0x4e, 0x31, 0x4e, 0x4f, 0x55, + 0x72, 0x63, 0x0a, 0x66, 0x68, 0x4e, 0x51, 0x4a, 0x46, 0x74, 0x42, 0x4a, 0x55, 0x39, 0x51, 0x47, + 0x35, 0x34, 0x4f, 0x2f, 0x46, 0x63, 0x67, 0x61, 0x4a, 0x4a, 0x2b, 0x53, 0x69, 0x79, 0x73, 0x4c, + 0x36, 0x4d, 0x49, 0x37, 0x50, 0x42, 0x4e, 0x55, 0x45, 0x31, 0x56, 0x6a, 0x6d, 0x59, 0x59, 0x38, + 0x35, 0x2f, 0x34, 0x57, 0x43, 0x57, 0x58, 0x66, 0x69, 0x47, 0x39, 0x75, 0x58, 0x79, 0x42, 0x6c, + 0x6b, 0x31, 0x55, 0x0a, 0x62, 0x70, 0x5a, 0x61, 0x4b, 0x72, 0x76, 0x51, 0x59, 0x4b, 0x64, 0x59, + 0x52, 0x50, 0x5a, 0x39, 0x48, 0x71, 0x66, 0x76, 0x42, 0x43, 0x6b, 0x6d, 0x68, 0x4a, 0x53, 0x36, + 0x6e, 0x4a, 0x57, 0x75, 0x38, 0x53, 0x39, 0x41, 0x43, 0x4a, 0x34, 0x47, 0x47, 0x51, 0x6d, 0x63, + 0x54, 0x69, 0x68, 0x71, 0x35, 0x6f, 0x72, 0x5a, 0x6f, 0x57, 0x73, 0x75, 0x32, 0x2b, 0x46, 0x7a, + 0x4d, 0x71, 0x45, 0x6b, 0x0a, 0x4d, 0x69, 0x2f, 0x47, 0x52, 0x6a, 0x2b, 0x4d, 0x53, 0x70, 0x6f, + 0x57, 0x39, 0x68, 0x55, 0x74, 0x44, 0x6a, 0x42, 0x33, 0x6a, 0x74, 0x63, 0x4b, 0x31, 0x73, 0x68, + 0x38, 0x53, 0x46, 0x74, 0x66, 0x48, 0x49, 0x44, 0x42, 0x66, 0x31, 0x4b, 0x53, 0x4c, 0x5a, 0x46, + 0x6b, 0x4c, 0x6a, 0x55, 0x43, 0x4a, 0x75, 0x65, 0x6b, 0x6d, 0x67, 0x31, 0x47, 0x78, 0x63, 0x34, + 0x70, 0x37, 0x6f, 0x78, 0x65, 0x0a, 0x6f, 0x45, 0x43, 0x49, 0x6b, 0x57, 0x4e, 0x54, 0x30, 0x52, + 0x4e, 0x53, 0x64, 0x4a, 0x6f, 0x2b, 0x73, 0x4f, 0x63, 0x6d, 0x6a, 0x59, 0x38, 0x6a, 0x32, 0x77, + 0x43, 0x4e, 0x69, 0x7a, 0x6c, 0x32, 0x76, 0x36, 0x42, 0x43, 0x72, 0x41, 0x57, 0x6f, 0x75, 0x4d, + 0x68, 0x6f, 0x78, 0x6a, 0x6c, 0x54, 0x41, 0x33, 0x33, 0x66, 0x43, 0x73, 0x2b, 0x2b, 0x6c, 0x58, + 0x6b, 0x4d, 0x2b, 0x79, 0x38, 0x6e, 0x0a, 0x46, 0x7a, 0x41, 0x6f, 0x75, 0x67, 0x68, 0x4b, 0x62, + 0x56, 0x31, 0x43, 0x69, 0x71, 0x59, 0x6a, 0x65, 0x68, 0x36, 0x6d, 0x56, 0x6a, 0x38, 0x68, 0x69, + 0x30, 0x39, 0x32, 0x55, 0x66, 0x33, 0x6a, 0x62, 0x43, 0x78, 0x6c, 0x4a, 0x73, 0x6f, 0x73, 0x46, + 0x2b, 0x4a, 0x65, 0x78, 0x54, 0x59, 0x56, 0x64, 0x41, 0x4e, 0x36, 0x74, 0x72, 0x50, 0x75, 0x4c, + 0x2f, 0x4a, 0x51, 0x4b, 0x66, 0x4b, 0x54, 0x0a, 0x4a, 0x39, 0x74, 0x31, 0x44, 0x62, 0x71, 0x6e, + 0x44, 0x74, 0x38, 0x50, 0x75, 0x43, 0x55, 0x45, 0x67, 0x63, 0x44, 0x76, 0x71, 0x48, 0x51, 0x4a, + 0x58, 0x58, 0x34, 0x53, 0x33, 0x59, 0x66, 0x65, 0x57, 0x62, 0x6e, 0x74, 0x51, 0x63, 0x36, 0x62, + 0x5a, 0x34, 0x4a, 0x5a, 0x44, 0x5a, 0x63, 0x46, 0x35, 0x6f, 0x67, 0x39, 0x47, 0x69, 0x6f, 0x61, + 0x5a, 0x2b, 0x75, 0x55, 0x45, 0x63, 0x4e, 0x62, 0x0a, 0x47, 0x4d, 0x32, 0x76, 0x33, 0x31, 0x5a, + 0x44, 0x74, 0x31, 0x45, 0x46, 0x41, 0x7a, 0x74, 0x6d, 0x74, 0x46, 0x74, 0x72, 0x70, 0x68, 0x52, + 0x50, 0x79, 0x5a, 0x4e, 0x61, 0x76, 0x39, 0x73, 0x63, 0x52, 0x77, 0x75, 0x50, 0x37, 0x51, 0x72, + 0x49, 0x62, 0x63, 0x66, 0x45, 0x63, 0x63, 0x51, 0x55, 0x70, 0x33, 0x61, 0x2f, 0x62, 0x62, 0x31, + 0x49, 0x51, 0x50, 0x4b, 0x2b, 0x4b, 0x59, 0x50, 0x67, 0x0a, 0x31, 0x50, 0x61, 0x67, 0x58, 0x57, + 0x59, 0x44, 0x62, 0x69, 0x6c, 0x55, 0x42, 0x4a, 0x57, 0x6d, 0x69, 0x32, 0x52, 0x31, 0x69, 0x52, + 0x4b, 0x78, 0x39, 0x59, 0x4e, 0x61, 0x68, 0x34, 0x45, 0x51, 0x49, 0x6f, 0x49, 0x72, 0x61, 0x61, + 0x66, 0x54, 0x6a, 0x78, 0x73, 0x6f, 0x6e, 0x50, 0x2f, 0x30, 0x55, 0x79, 0x62, 0x6b, 0x71, 0x65, + 0x6e, 0x73, 0x4b, 0x4d, 0x47, 0x71, 0x58, 0x54, 0x2f, 0x55, 0x0a, 0x64, 0x34, 0x52, 0x33, 0x36, + 0x50, 0x31, 0x64, 0x44, 0x43, 0x6b, 0x6b, 0x4e, 0x2b, 0x4b, 0x59, 0x64, 0x55, 0x42, 0x4d, 0x44, + 0x72, 0x76, 0x66, 0x69, 0x51, 0x34, 0x47, 0x64, 0x4e, 0x6a, 0x4c, 0x5a, 0x61, 0x2b, 0x49, 0x32, + 0x75, 0x50, 0x50, 0x6c, 0x55, 0x6e, 0x76, 0x72, 0x38, 0x7a, 0x67, 0x43, 0x73, 0x45, 0x77, 0x4f, + 0x7a, 0x75, 0x46, 0x32, 0x5a, 0x73, 0x32, 0x4f, 0x6f, 0x32, 0x50, 0x0a, 0x50, 0x52, 0x63, 0x7a, + 0x50, 0x50, 0x5a, 0x44, 0x2b, 0x61, 0x36, 0x46, 0x64, 0x74, 0x39, 0x44, 0x65, 0x74, 0x73, 0x47, + 0x77, 0x36, 0x35, 0x32, 0x49, 0x47, 0x38, 0x65, 0x49, 0x59, 0x70, 0x33, 0x63, 0x47, 0x2f, 0x4b, + 0x43, 0x74, 0x66, 0x6b, 0x6f, 0x30, 0x76, 0x58, 0x6f, 0x46, 0x4a, 0x73, 0x43, 0x4e, 0x4b, 0x36, + 0x2f, 0x45, 0x6e, 0x65, 0x31, 0x4e, 0x66, 0x72, 0x45, 0x6e, 0x7a, 0x79, 0x0a, 0x32, 0x30, 0x67, + 0x7a, 0x7a, 0x39, 0x4a, 0x55, 0x6d, 0x35, 0x7a, 0x68, 0x73, 0x38, 0x54, 0x68, 0x59, 0x63, 0x34, + 0x75, 0x35, 0x6f, 0x41, 0x2f, 0x78, 0x48, 0x6f, 0x79, 0x76, 0x79, 0x57, 0x46, 0x38, 0x74, 0x39, + 0x31, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x59, 0x44, 0x42, 0x65, 0x4d, 0x41, 0x38, + 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x0a, 0x4d, 0x41, + 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, + 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, + 0x51, 0x57, 0x42, 0x42, 0x52, 0x6c, 0x76, 0x43, 0x32, 0x55, 0x61, 0x31, 0x32, 0x64, 0x34, 0x59, + 0x51, 0x31, 0x4f, 0x51, 0x79, 0x2b, 0x32, 0x43, 0x76, 0x4c, 0x6e, 0x4c, 0x47, 0x72, 0x0a, 0x41, + 0x44, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, + 0x42, 0x54, 0x53, 0x57, 0x39, 0x59, 0x70, 0x5a, 0x4c, 0x43, 0x73, 0x74, 0x43, 0x30, 0x50, 0x54, + 0x39, 0x32, 0x39, 0x5a, 0x56, 0x6d, 0x43, 0x78, 0x30, 0x48, 0x30, 0x4a, 0x6a, 0x41, 0x4e, 0x42, + 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x0a, + 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x67, 0x65, 0x48, 0x74, 0x75, 0x57, 0x4b, 0x38, + 0x35, 0x31, 0x68, 0x4f, 0x48, 0x58, 0x55, 0x52, 0x62, 0x59, 0x71, 0x43, 0x75, 0x37, 0x4f, 0x58, + 0x6c, 0x35, 0x61, 0x73, 0x69, 0x2b, 0x61, 0x39, 0x44, 0x59, 0x72, 0x4b, 0x66, 0x34, 0x4c, 0x50, + 0x71, 0x35, 0x50, 0x78, 0x72, 0x48, 0x38, 0x2b, 0x64, 0x56, 0x33, 0x6c, 0x49, 0x44, 0x6a, 0x38, + 0x0a, 0x59, 0x47, 0x5a, 0x6c, 0x34, 0x34, 0x64, 0x37, 0x34, 0x6f, 0x6c, 0x38, 0x4a, 0x72, 0x71, + 0x2f, 0x4b, 0x59, 0x64, 0x39, 0x34, 0x71, 0x53, 0x46, 0x76, 0x71, 0x30, 0x39, 0x39, 0x43, 0x66, + 0x42, 0x6c, 0x53, 0x65, 0x61, 0x6d, 0x44, 0x4d, 0x71, 0x4a, 0x30, 0x54, 0x4d, 0x76, 0x68, 0x4d, + 0x62, 0x37, 0x38, 0x68, 0x75, 0x7a, 0x48, 0x4f, 0x63, 0x59, 0x73, 0x72, 0x73, 0x6e, 0x4c, 0x4f, + 0x77, 0x0a, 0x45, 0x32, 0x6f, 0x46, 0x43, 0x65, 0x41, 0x45, 0x2b, 0x78, 0x77, 0x2f, 0x68, 0x2f, + 0x53, 0x4c, 0x75, 0x62, 0x76, 0x6e, 0x59, 0x6d, 0x43, 0x43, 0x5a, 0x67, 0x4f, 0x50, 0x54, 0x4f, + 0x32, 0x74, 0x51, 0x5a, 0x72, 0x34, 0x4d, 0x39, 0x75, 0x44, 0x6e, 0x52, 0x37, 0x7a, 0x49, 0x66, + 0x38, 0x6c, 0x59, 0x47, 0x56, 0x33, 0x50, 0x6d, 0x43, 0x6e, 0x78, 0x63, 0x78, 0x2b, 0x4a, 0x68, + 0x76, 0x65, 0x0a, 0x6d, 0x74, 0x47, 0x62, 0x6b, 0x2f, 0x6d, 0x35, 0x6a, 0x73, 0x68, 0x52, 0x6c, + 0x2b, 0x44, 0x30, 0x62, 0x53, 0x64, 0x76, 0x52, 0x36, 0x52, 0x56, 0x37, 0x71, 0x4b, 0x72, 0x70, + 0x4c, 0x50, 0x5a, 0x38, 0x74, 0x42, 0x79, 0x46, 0x2b, 0x53, 0x2b, 0x63, 0x45, 0x4d, 0x6f, 0x6b, + 0x6f, 0x47, 0x35, 0x6d, 0x63, 0x59, 0x38, 0x68, 0x75, 0x39, 0x38, 0x7a, 0x36, 0x79, 0x65, 0x73, + 0x43, 0x73, 0x70, 0x0a, 0x79, 0x43, 0x64, 0x46, 0x74, 0x55, 0x45, 0x34, 0x69, 0x77, 0x64, 0x70, + 0x4b, 0x2f, 0x55, 0x56, 0x48, 0x61, 0x31, 0x39, 0x44, 0x52, 0x72, 0x6f, 0x48, 0x64, 0x41, 0x48, + 0x61, 0x36, 0x37, 0x79, 0x38, 0x79, 0x73, 0x50, 0x46, 0x69, 0x34, 0x65, 0x76, 0x63, 0x50, 0x32, + 0x44, 0x65, 0x48, 0x50, 0x70, 0x32, 0x6f, 0x78, 0x4a, 0x73, 0x2b, 0x38, 0x4b, 0x73, 0x73, 0x4c, + 0x44, 0x31, 0x30, 0x6f, 0x0a, 0x78, 0x6a, 0x4a, 0x37, 0x6b, 0x43, 0x64, 0x6e, 0x70, 0x78, 0x4a, + 0x5a, 0x64, 0x49, 0x74, 0x41, 0x39, 0x76, 0x54, 0x44, 0x75, 0x69, 0x48, 0x57, 0x79, 0x66, 0x69, + 0x79, 0x4a, 0x75, 0x35, 0x6f, 0x30, 0x71, 0x4e, 0x4d, 0x49, 0x50, 0x50, 0x57, 0x4d, 0x76, 0x51, + 0x46, 0x45, 0x74, 0x6f, 0x61, 0x76, 0x34, 0x42, 0x67, 0x2b, 0x32, 0x74, 0x66, 0x4b, 0x70, 0x61, + 0x52, 0x41, 0x33, 0x57, 0x64, 0x0a, 0x42, 0x65, 0x53, 0x2f, 0x37, 0x4d, 0x45, 0x6e, 0x36, 0x65, + 0x72, 0x37, 0x73, 0x43, 0x64, 0x2b, 0x42, 0x35, 0x2b, 0x4d, 0x79, 0x4b, 0x78, 0x46, 0x4f, 0x66, + 0x75, 0x52, 0x74, 0x5a, 0x70, 0x6c, 0x71, 0x35, 0x41, 0x42, 0x4c, 0x69, 0x37, 0x53, 0x35, 0x64, + 0x76, 0x6d, 0x6e, 0x79, 0x48, 0x37, 0x51, 0x2f, 0x76, 0x4b, 0x53, 0x51, 0x53, 0x75, 0x39, 0x34, + 0x66, 0x66, 0x52, 0x78, 0x61, 0x4c, 0x0a, 0x56, 0x69, 0x63, 0x6e, 0x6f, 0x6f, 0x4a, 0x4d, 0x38, + 0x44, 0x6e, 0x47, 0x6c, 0x70, 0x43, 0x75, 0x35, 0x35, 0x61, 0x50, 0x46, 0x56, 0x6e, 0x54, 0x46, + 0x6a, 0x37, 0x30, 0x43, 0x47, 0x61, 0x50, 0x72, 0x61, 0x4b, 0x72, 0x69, 0x6a, 0x62, 0x68, 0x35, + 0x4e, 0x4a, 0x51, 0x43, 0x7a, 0x6c, 0x62, 0x31, 0x2f, 0x65, 0x52, 0x48, 0x31, 0x6c, 0x4d, 0x55, + 0x6b, 0x31, 0x57, 0x37, 0x6d, 0x41, 0x68, 0x0a, 0x75, 0x39, 0x33, 0x44, 0x2b, 0x79, 0x2f, 0x65, + 0x72, 0x46, 0x4f, 0x75, 0x2f, 0x6a, 0x58, 0x73, 0x44, 0x6e, 0x69, 0x34, 0x4a, 0x4c, 0x68, 0x72, + 0x4d, 0x65, 0x34, 0x45, 0x7a, 0x6d, 0x78, 0x75, 0x2b, 0x6c, 0x7a, 0x6b, 0x6b, 0x58, 0x43, 0x68, + 0x36, 0x39, 0x36, 0x58, 0x6a, 0x59, 0x49, 0x45, 0x62, 0x41, 0x42, 0x6f, 0x66, 0x62, 0x45, 0x4c, + 0x30, 0x74, 0x46, 0x56, 0x50, 0x6e, 0x68, 0x37, 0x0a, 0x51, 0x55, 0x42, 0x37, 0x65, 0x59, 0x4a, + 0x63, 0x67, 0x6b, 0x61, 0x42, 0x6e, 0x39, 0x64, 0x6b, 0x31, 0x38, 0x61, 0x73, 0x6f, 0x78, 0x73, + 0x54, 0x41, 0x51, 0x73, 0x30, 0x6b, 0x41, 0x61, 0x52, 0x71, 0x79, 0x70, 0x73, 0x63, 0x4a, 0x46, + 0x44, 0x56, 0x6d, 0x67, 0x74, 0x45, 0x78, 0x53, 0x4e, 0x54, 0x72, 0x4a, 0x78, 0x50, 0x62, 0x7a, + 0x52, 0x33, 0x6d, 0x72, 0x2f, 0x69, 0x6f, 0x64, 0x6d, 0x0a, 0x5a, 0x7a, 0x57, 0x37, 0x54, 0x39, + 0x59, 0x33, 0x4f, 0x4e, 0x45, 0x31, 0x67, 0x79, 0x74, 0x38, 0x75, 0x51, 0x53, 0x44, 0x58, 0x62, + 0x4d, 0x6c, 0x6b, 0x71, 0x6d, 0x55, 0x76, 0x49, 0x61, 0x6f, 0x42, 0x4d, 0x79, 0x43, 0x4c, 0x56, + 0x31, 0x31, 0x6a, 0x44, 0x66, 0x6a, 0x6b, 0x51, 0x47, 0x78, 0x41, 0x53, 0x77, 0x3d, 0x0a, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, + 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +/* Contains the application certificate */ +#define INTERMEDIATE_CRL_PEM_LENGTH 1121 +UA_Byte INTERMEDIATE_CRL_PEM_DATA[1121] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, + 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x45, 0x6a, 0x43, + 0x42, 0x2b, 0x77, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, + 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x75, 0x4d, 0x51, 0x73, + 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52, 0x54, 0x45, + 0x4f, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x41, 0x77, 0x46, 0x55, 0x33, + 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x44, 0x54, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, + 0x63, 0x4d, 0x42, 0x45, 0x4e, 0x70, 0x64, 0x48, 0x6b, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x44, 0x45, 0x39, 0x79, 0x5a, 0x32, 0x46, 0x75, 0x61, 0x58, + 0x70, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x48, 0x54, 0x33, 0x4a, 0x6e, 0x56, 0x57, 0x35, 0x70, 0x64, + 0x44, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x4f, 0x53, + 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x74, 0x5a, 0x57, 0x52, 0x70, 0x59, 0x58, 0x52, 0x6c, 0x51, + 0x30, 0x45, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x44, 0x6b, 0x78, 0x0a, 0x4d, 0x54, 0x45, 0x30, + 0x4d, 0x44, 0x49, 0x7a, 0x4d, 0x6c, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x54, 0x41, 0x78, + 0x4d, 0x54, 0x45, 0x30, 0x4d, 0x44, 0x49, 0x7a, 0x4d, 0x6c, 0x6f, 0x77, 0x4a, 0x7a, 0x41, 0x6c, + 0x41, 0x68, 0x51, 0x49, 0x69, 0x49, 0x59, 0x35, 0x35, 0x39, 0x4e, 0x34, 0x73, 0x6f, 0x6d, 0x6b, + 0x2b, 0x49, 0x76, 0x32, 0x63, 0x51, 0x44, 0x44, 0x64, 0x6e, 0x67, 0x4d, 0x0a, 0x6f, 0x52, 0x63, + 0x4e, 0x4d, 0x6a, 0x51, 0x77, 0x4f, 0x54, 0x45, 0x78, 0x4d, 0x54, 0x51, 0x77, 0x4d, 0x6a, 0x49, + 0x32, 0x57, 0x71, 0x41, 0x77, 0x4d, 0x43, 0x34, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, + 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, 0x41, 0x55, 0x5a, 0x62, 0x77, 0x74, 0x6c, 0x47, 0x74, + 0x64, 0x6e, 0x65, 0x47, 0x45, 0x4e, 0x54, 0x6b, 0x4d, 0x76, 0x74, 0x67, 0x72, 0x0a, 0x79, 0x35, + 0x79, 0x78, 0x71, 0x77, 0x41, 0x77, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x55, 0x42, 0x41, + 0x51, 0x43, 0x41, 0x68, 0x41, 0x46, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, + 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x43, 0x41, 0x51, + 0x41, 0x73, 0x6b, 0x45, 0x4f, 0x65, 0x36, 0x4d, 0x56, 0x36, 0x62, 0x54, 0x79, 0x6c, 0x0a, 0x41, + 0x56, 0x50, 0x48, 0x71, 0x47, 0x55, 0x69, 0x42, 0x64, 0x41, 0x53, 0x76, 0x75, 0x68, 0x33, 0x6e, + 0x6a, 0x68, 0x48, 0x4f, 0x6d, 0x5a, 0x42, 0x43, 0x32, 0x31, 0x77, 0x34, 0x51, 0x71, 0x73, 0x7a, + 0x43, 0x32, 0x48, 0x65, 0x38, 0x33, 0x4d, 0x58, 0x66, 0x63, 0x41, 0x7a, 0x4b, 0x6b, 0x51, 0x55, + 0x61, 0x6d, 0x4c, 0x5a, 0x45, 0x76, 0x43, 0x4d, 0x32, 0x2f, 0x77, 0x4e, 0x74, 0x58, 0x6c, 0x0a, + 0x59, 0x55, 0x67, 0x79, 0x66, 0x53, 0x70, 0x52, 0x4e, 0x6b, 0x70, 0x56, 0x6e, 0x6a, 0x4a, 0x66, + 0x35, 0x4f, 0x6d, 0x6a, 0x50, 0x75, 0x53, 0x75, 0x46, 0x76, 0x39, 0x69, 0x64, 0x78, 0x46, 0x68, + 0x34, 0x66, 0x44, 0x35, 0x37, 0x71, 0x41, 0x38, 0x2f, 0x51, 0x70, 0x4f, 0x31, 0x61, 0x61, 0x44, + 0x65, 0x71, 0x4d, 0x41, 0x74, 0x47, 0x37, 0x72, 0x53, 0x77, 0x4a, 0x69, 0x2b, 0x67, 0x7a, 0x69, + 0x0a, 0x36, 0x35, 0x38, 0x36, 0x6d, 0x73, 0x33, 0x58, 0x72, 0x72, 0x7a, 0x51, 0x2b, 0x33, 0x69, + 0x54, 0x69, 0x50, 0x52, 0x49, 0x44, 0x45, 0x4b, 0x71, 0x2b, 0x72, 0x69, 0x69, 0x2b, 0x52, 0x4b, + 0x68, 0x41, 0x4b, 0x64, 0x79, 0x57, 0x63, 0x2f, 0x79, 0x6f, 0x4a, 0x6c, 0x4b, 0x75, 0x30, 0x2f, + 0x6f, 0x42, 0x6b, 0x73, 0x63, 0x77, 0x67, 0x65, 0x58, 0x42, 0x61, 0x52, 0x33, 0x4c, 0x4f, 0x6b, + 0x5a, 0x0a, 0x53, 0x6b, 0x2b, 0x73, 0x76, 0x70, 0x4a, 0x6f, 0x32, 0x36, 0x75, 0x59, 0x4d, 0x45, + 0x52, 0x36, 0x43, 0x31, 0x70, 0x37, 0x42, 0x48, 0x79, 0x43, 0x78, 0x62, 0x59, 0x4c, 0x4a, 0x30, + 0x58, 0x61, 0x4d, 0x46, 0x51, 0x54, 0x54, 0x57, 0x76, 0x37, 0x37, 0x34, 0x6f, 0x33, 0x63, 0x4a, + 0x42, 0x53, 0x45, 0x58, 0x79, 0x74, 0x2b, 0x58, 0x78, 0x52, 0x69, 0x75, 0x6e, 0x6c, 0x43, 0x49, + 0x42, 0x31, 0x0a, 0x75, 0x46, 0x77, 0x36, 0x43, 0x44, 0x44, 0x2f, 0x57, 0x63, 0x76, 0x72, 0x43, + 0x76, 0x59, 0x55, 0x77, 0x71, 0x63, 0x43, 0x77, 0x31, 0x2b, 0x53, 0x47, 0x66, 0x46, 0x2b, 0x68, + 0x51, 0x74, 0x6f, 0x77, 0x4d, 0x33, 0x6a, 0x4c, 0x73, 0x33, 0x71, 0x50, 0x57, 0x59, 0x61, 0x2b, + 0x66, 0x67, 0x69, 0x58, 0x33, 0x71, 0x70, 0x38, 0x72, 0x53, 0x77, 0x65, 0x39, 0x32, 0x69, 0x5a, + 0x76, 0x44, 0x4e, 0x0a, 0x7a, 0x4e, 0x72, 0x6f, 0x34, 0x64, 0x5a, 0x4a, 0x46, 0x42, 0x59, 0x65, + 0x61, 0x55, 0x70, 0x30, 0x46, 0x48, 0x6c, 0x6e, 0x71, 0x56, 0x2b, 0x46, 0x6c, 0x72, 0x77, 0x32, + 0x5a, 0x6c, 0x38, 0x41, 0x48, 0x53, 0x4e, 0x33, 0x69, 0x75, 0x70, 0x53, 0x33, 0x74, 0x74, 0x2b, + 0x39, 0x56, 0x31, 0x76, 0x63, 0x75, 0x45, 0x34, 0x2b, 0x70, 0x78, 0x64, 0x68, 0x73, 0x32, 0x44, + 0x4c, 0x78, 0x38, 0x46, 0x0a, 0x78, 0x6d, 0x6d, 0x39, 0x41, 0x67, 0x66, 0x50, 0x32, 0x49, 0x71, + 0x33, 0x62, 0x47, 0x4c, 0x4a, 0x69, 0x42, 0x32, 0x76, 0x39, 0x74, 0x4d, 0x76, 0x70, 0x63, 0x32, + 0x63, 0x4e, 0x61, 0x45, 0x58, 0x33, 0x4b, 0x34, 0x4a, 0x48, 0x4f, 0x48, 0x78, 0x38, 0x6a, 0x6b, + 0x65, 0x34, 0x6b, 0x6f, 0x66, 0x66, 0x4f, 0x44, 0x70, 0x77, 0x36, 0x70, 0x48, 0x71, 0x71, 0x61, + 0x64, 0x73, 0x47, 0x54, 0x63, 0x0a, 0x6d, 0x55, 0x56, 0x75, 0x4f, 0x45, 0x66, 0x35, 0x47, 0x72, + 0x70, 0x77, 0x37, 0x67, 0x54, 0x68, 0x70, 0x41, 0x52, 0x2b, 0x38, 0x37, 0x32, 0x45, 0x66, 0x41, + 0x43, 0x58, 0x72, 0x4a, 0x6f, 0x33, 0x63, 0x73, 0x45, 0x2b, 0x48, 0x74, 0x49, 0x2b, 0x50, 0x69, + 0x4b, 0x48, 0x58, 0x37, 0x6f, 0x38, 0x47, 0x75, 0x61, 0x49, 0x63, 0x56, 0x6d, 0x77, 0x42, 0x74, + 0x59, 0x33, 0x35, 0x52, 0x75, 0x44, 0x0a, 0x4e, 0x56, 0x6f, 0x34, 0x58, 0x36, 0x36, 0x49, 0x52, + 0x47, 0x6d, 0x65, 0x38, 0x4a, 0x56, 0x58, 0x64, 0x50, 0x4c, 0x35, 0x6b, 0x76, 0x6b, 0x78, 0x6e, + 0x63, 0x4f, 0x72, 0x73, 0x77, 0x30, 0x42, 0x75, 0x61, 0x48, 0x61, 0x63, 0x76, 0x41, 0x58, 0x6f, + 0x2b, 0x79, 0x42, 0x49, 0x66, 0x4e, 0x78, 0x6b, 0x54, 0x37, 0x67, 0x35, 0x78, 0x69, 0x46, 0x74, + 0x58, 0x49, 0x41, 0x70, 0x36, 0x74, 0x72, 0x0a, 0x36, 0x63, 0x36, 0x52, 0x30, 0x6e, 0x78, 0x70, + 0x63, 0x7a, 0x77, 0x6c, 0x68, 0x43, 0x55, 0x39, 0x34, 0x37, 0x4c, 0x48, 0x34, 0x62, 0x51, 0x74, + 0x66, 0x33, 0x6e, 0x51, 0x6f, 0x30, 0x4e, 0x6e, 0x6e, 0x39, 0x73, 0x74, 0x44, 0x39, 0x38, 0x67, + 0x31, 0x33, 0x6e, 0x63, 0x54, 0x59, 0x59, 0x73, 0x73, 0x32, 0x73, 0x78, 0x35, 0x64, 0x61, 0x5a, + 0x75, 0x56, 0x53, 0x45, 0x79, 0x57, 0x64, 0x72, 0x0a, 0x4e, 0x6a, 0x66, 0x7a, 0x56, 0x33, 0x5a, + 0x49, 0x4d, 0x77, 0x4a, 0x4f, 0x2f, 0x2b, 0x39, 0x6f, 0x67, 0x4e, 0x51, 0x45, 0x37, 0x42, 0x69, + 0x75, 0x35, 0x78, 0x2f, 0x55, 0x62, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, + 0x4e, 0x44, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x0a +}; + +#define INTERMEDIATE_EMPTY_CRL_PEM_LENGTH 1064 +UA_Byte INTERMEDIATE_EMPTY_CRL_PEM_DATA[1064] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, + 0x43, 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x36, 0x54, 0x43, + 0x42, 0x30, 0x67, 0x49, 0x42, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, + 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x75, 0x4d, 0x51, 0x73, + 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x45, 0x52, 0x54, 0x45, + 0x4f, 0x4d, 0x41, 0x77, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0a, 0x43, 0x41, 0x77, 0x46, 0x55, 0x33, + 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x44, 0x54, 0x41, 0x4c, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, + 0x63, 0x4d, 0x42, 0x45, 0x4e, 0x70, 0x64, 0x48, 0x6b, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x44, 0x45, 0x39, 0x79, 0x5a, 0x32, 0x46, 0x75, 0x61, 0x58, + 0x70, 0x68, 0x64, 0x47, 0x6c, 0x76, 0x62, 0x6a, 0x45, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x45, 0x43, 0x77, 0x77, 0x48, 0x54, 0x33, 0x4a, 0x6e, 0x56, 0x57, 0x35, 0x70, 0x64, + 0x44, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x4f, 0x53, + 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x74, 0x5a, 0x57, 0x52, 0x70, 0x59, 0x58, 0x52, 0x6c, 0x51, + 0x30, 0x45, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x44, 0x6b, 0x78, 0x0a, 0x4d, 0x54, 0x45, 0x79, + 0x4d, 0x44, 0x51, 0x77, 0x4e, 0x6c, 0x6f, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x54, 0x41, 0x78, + 0x4d, 0x54, 0x45, 0x79, 0x4d, 0x44, 0x51, 0x77, 0x4e, 0x6c, 0x71, 0x67, 0x4d, 0x44, 0x41, 0x75, + 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, + 0x46, 0x47, 0x57, 0x38, 0x4c, 0x5a, 0x52, 0x72, 0x58, 0x5a, 0x33, 0x68, 0x0a, 0x68, 0x44, 0x55, + 0x35, 0x44, 0x4c, 0x37, 0x59, 0x4b, 0x38, 0x75, 0x63, 0x73, 0x61, 0x73, 0x41, 0x4d, 0x41, 0x73, + 0x47, 0x41, 0x31, 0x55, 0x64, 0x46, 0x41, 0x51, 0x45, 0x41, 0x67, 0x49, 0x51, 0x41, 0x6a, 0x41, + 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, + 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x64, 0x2b, 0x45, 0x39, 0x0a, 0x65, 0x56, + 0x4b, 0x44, 0x58, 0x4a, 0x6b, 0x62, 0x4c, 0x6b, 0x61, 0x65, 0x35, 0x41, 0x42, 0x70, 0x36, 0x4d, + 0x79, 0x4e, 0x44, 0x43, 0x6d, 0x54, 0x75, 0x39, 0x44, 0x6b, 0x2f, 0x56, 0x75, 0x4b, 0x72, 0x56, + 0x79, 0x78, 0x4e, 0x39, 0x69, 0x4c, 0x36, 0x52, 0x34, 0x69, 0x62, 0x41, 0x79, 0x52, 0x6a, 0x43, + 0x2b, 0x7a, 0x57, 0x6e, 0x42, 0x39, 0x6b, 0x66, 0x54, 0x73, 0x4b, 0x36, 0x77, 0x77, 0x0a, 0x6c, + 0x6a, 0x4b, 0x74, 0x31, 0x30, 0x75, 0x67, 0x47, 0x62, 0x67, 0x76, 0x33, 0x37, 0x72, 0x57, 0x57, + 0x78, 0x49, 0x45, 0x71, 0x57, 0x72, 0x68, 0x69, 0x35, 0x50, 0x58, 0x4d, 0x76, 0x63, 0x6b, 0x49, + 0x62, 0x59, 0x47, 0x35, 0x63, 0x77, 0x5a, 0x59, 0x7a, 0x61, 0x2f, 0x4f, 0x6b, 0x36, 0x2b, 0x66, + 0x34, 0x31, 0x61, 0x2b, 0x76, 0x51, 0x4d, 0x43, 0x48, 0x4a, 0x4a, 0x72, 0x6a, 0x44, 0x58, 0x0a, + 0x32, 0x41, 0x79, 0x6e, 0x6d, 0x45, 0x2b, 0x6b, 0x45, 0x72, 0x59, 0x52, 0x32, 0x54, 0x6d, 0x61, + 0x74, 0x4c, 0x7a, 0x49, 0x72, 0x62, 0x4f, 0x4f, 0x32, 0x66, 0x56, 0x61, 0x46, 0x36, 0x6d, 0x2f, + 0x61, 0x6f, 0x6b, 0x33, 0x2b, 0x70, 0x54, 0x64, 0x2f, 0x39, 0x4b, 0x7a, 0x61, 0x68, 0x52, 0x48, + 0x4f, 0x34, 0x4e, 0x55, 0x34, 0x78, 0x6b, 0x58, 0x38, 0x4a, 0x74, 0x5a, 0x69, 0x30, 0x4b, 0x54, + 0x0a, 0x68, 0x56, 0x6e, 0x44, 0x2f, 0x6a, 0x6a, 0x51, 0x36, 0x62, 0x54, 0x33, 0x58, 0x6a, 0x35, + 0x4a, 0x53, 0x45, 0x38, 0x6f, 0x35, 0x72, 0x59, 0x71, 0x4a, 0x2f, 0x74, 0x4c, 0x55, 0x47, 0x2b, + 0x4d, 0x4d, 0x39, 0x4e, 0x31, 0x4c, 0x75, 0x32, 0x6a, 0x4f, 0x57, 0x6e, 0x6d, 0x4e, 0x78, 0x55, + 0x44, 0x72, 0x4b, 0x70, 0x56, 0x6b, 0x6c, 0x59, 0x76, 0x37, 0x59, 0x6e, 0x52, 0x61, 0x33, 0x41, + 0x64, 0x0a, 0x5a, 0x4d, 0x2b, 0x7a, 0x75, 0x34, 0x35, 0x56, 0x4e, 0x69, 0x76, 0x4b, 0x4f, 0x30, + 0x79, 0x59, 0x33, 0x7a, 0x35, 0x74, 0x73, 0x4a, 0x74, 0x48, 0x48, 0x34, 0x36, 0x4a, 0x69, 0x46, + 0x49, 0x79, 0x54, 0x68, 0x43, 0x67, 0x35, 0x42, 0x6c, 0x68, 0x70, 0x47, 0x51, 0x6a, 0x54, 0x41, + 0x73, 0x72, 0x68, 0x64, 0x49, 0x61, 0x47, 0x4d, 0x50, 0x64, 0x39, 0x49, 0x6d, 0x58, 0x73, 0x44, + 0x65, 0x2f, 0x0a, 0x4c, 0x35, 0x51, 0x79, 0x58, 0x41, 0x4f, 0x58, 0x62, 0x4e, 0x31, 0x33, 0x74, + 0x39, 0x64, 0x74, 0x72, 0x72, 0x76, 0x76, 0x70, 0x6b, 0x38, 0x48, 0x34, 0x5a, 0x48, 0x43, 0x73, + 0x61, 0x4f, 0x39, 0x53, 0x36, 0x36, 0x43, 0x43, 0x67, 0x4a, 0x7a, 0x59, 0x47, 0x55, 0x47, 0x34, + 0x75, 0x54, 0x35, 0x79, 0x61, 0x54, 0x61, 0x75, 0x54, 0x34, 0x50, 0x67, 0x77, 0x6b, 0x2f, 0x78, + 0x68, 0x32, 0x55, 0x0a, 0x74, 0x59, 0x52, 0x72, 0x4f, 0x39, 0x2b, 0x72, 0x51, 0x50, 0x4d, 0x62, + 0x4d, 0x45, 0x79, 0x33, 0x52, 0x74, 0x45, 0x67, 0x44, 0x79, 0x4c, 0x59, 0x70, 0x38, 0x6b, 0x69, + 0x6d, 0x44, 0x77, 0x71, 0x5a, 0x6d, 0x31, 0x45, 0x53, 0x72, 0x4a, 0x6e, 0x51, 0x6b, 0x7a, 0x71, + 0x76, 0x64, 0x78, 0x74, 0x46, 0x5a, 0x64, 0x54, 0x4b, 0x7a, 0x62, 0x32, 0x2b, 0x2b, 0x46, 0x6c, + 0x79, 0x5a, 0x45, 0x73, 0x0a, 0x56, 0x6d, 0x51, 0x73, 0x78, 0x70, 0x75, 0x4d, 0x4c, 0x67, 0x6a, + 0x73, 0x57, 0x35, 0x30, 0x49, 0x39, 0x2b, 0x46, 0x2f, 0x63, 0x68, 0x6a, 0x48, 0x37, 0x64, 0x77, + 0x65, 0x77, 0x37, 0x36, 0x39, 0x72, 0x50, 0x4c, 0x44, 0x62, 0x45, 0x79, 0x36, 0x4d, 0x6f, 0x74, + 0x4c, 0x62, 0x72, 0x67, 0x48, 0x69, 0x61, 0x66, 0x67, 0x44, 0x54, 0x61, 0x37, 0x6a, 0x76, 0x52, + 0x46, 0x55, 0x36, 0x54, 0x56, 0x0a, 0x78, 0x2f, 0x77, 0x68, 0x61, 0x6e, 0x50, 0x2f, 0x7a, 0x59, + 0x34, 0x65, 0x49, 0x4c, 0x72, 0x4f, 0x62, 0x43, 0x7a, 0x31, 0x4e, 0x50, 0x4c, 0x52, 0x6f, 0x35, + 0x70, 0x54, 0x6c, 0x6d, 0x49, 0x7a, 0x58, 0x36, 0x4d, 0x2f, 0x37, 0x79, 0x51, 0x45, 0x79, 0x34, + 0x34, 0x6a, 0x2f, 0x4a, 0x39, 0x53, 0x35, 0x62, 0x4d, 0x6a, 0x4e, 0x67, 0x2b, 0x75, 0x36, 0x72, + 0x43, 0x30, 0x54, 0x77, 0x53, 0x55, 0x0a, 0x6b, 0x64, 0x41, 0x68, 0x68, 0x64, 0x61, 0x48, 0x4e, + 0x75, 0x52, 0x4d, 0x35, 0x6a, 0x4f, 0x68, 0x6a, 0x57, 0x35, 0x4d, 0x46, 0x63, 0x71, 0x56, 0x36, + 0x4e, 0x35, 0x4d, 0x46, 0x6e, 0x34, 0x38, 0x69, 0x79, 0x52, 0x4b, 0x46, 0x54, 0x50, 0x78, 0x37, + 0x54, 0x4b, 0x68, 0x46, 0x38, 0x34, 0x6d, 0x64, 0x53, 0x2b, 0x56, 0x39, 0x2b, 0x43, 0x47, 0x52, + 0x51, 0x53, 0x65, 0x46, 0x70, 0x70, 0x38, 0x0a, 0x4a, 0x6e, 0x69, 0x49, 0x73, 0x6a, 0x71, 0x50, + 0x59, 0x6a, 0x68, 0x6e, 0x34, 0x6f, 0x74, 0x38, 0x52, 0x37, 0x6b, 0x64, 0x68, 0x79, 0x74, 0x38, + 0x31, 0x69, 0x31, 0x56, 0x53, 0x6e, 0x78, 0x33, 0x73, 0x70, 0x74, 0x33, 0x7a, 0x77, 0x30, 0x3d, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x58, 0x35, 0x30, 0x39, 0x20, 0x43, + 0x52, 0x4c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +#define APPLICATION_KEY_DER_LENGTH 1704 +UA_Byte APPLICATION_KEY_DER_DATA[1704] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, + 0x76, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, + 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, 0x42, 0x4b, 0x67, 0x77, + 0x67, 0x67, 0x53, 0x6b, 0x41, 0x67, 0x45, 0x41, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x55, + 0x55, 0x6a, 0x55, 0x6c, 0x68, 0x39, 0x46, 0x73, 0x6f, 0x70, 0x49, 0x6d, 0x0a, 0x50, 0x4b, 0x5a, + 0x44, 0x59, 0x66, 0x46, 0x75, 0x76, 0x2f, 0x58, 0x70, 0x46, 0x68, 0x58, 0x55, 0x36, 0x63, 0x4f, + 0x74, 0x4f, 0x30, 0x6e, 0x75, 0x65, 0x79, 0x4d, 0x4b, 0x65, 0x5a, 0x4a, 0x39, 0x66, 0x50, 0x78, + 0x4b, 0x36, 0x52, 0x62, 0x4e, 0x49, 0x52, 0x65, 0x7a, 0x6e, 0x79, 0x78, 0x61, 0x44, 0x2b, 0x44, + 0x2f, 0x4d, 0x6c, 0x72, 0x46, 0x44, 0x54, 0x73, 0x7a, 0x44, 0x66, 0x71, 0x4b, 0x0a, 0x4c, 0x61, + 0x50, 0x70, 0x4d, 0x42, 0x49, 0x52, 0x44, 0x48, 0x76, 0x32, 0x51, 0x52, 0x68, 0x59, 0x73, 0x52, + 0x49, 0x57, 0x30, 0x61, 0x69, 0x46, 0x70, 0x66, 0x70, 0x38, 0x38, 0x30, 0x68, 0x53, 0x74, 0x42, + 0x41, 0x69, 0x52, 0x2f, 0x43, 0x59, 0x4f, 0x73, 0x37, 0x6e, 0x34, 0x34, 0x5a, 0x66, 0x73, 0x50, + 0x6f, 0x75, 0x75, 0x4f, 0x34, 0x66, 0x79, 0x33, 0x6a, 0x5a, 0x6f, 0x37, 0x79, 0x75, 0x0a, 0x35, + 0x6e, 0x65, 0x4c, 0x4f, 0x47, 0x46, 0x32, 0x72, 0x75, 0x73, 0x72, 0x7a, 0x75, 0x42, 0x35, 0x62, + 0x45, 0x6f, 0x71, 0x44, 0x58, 0x6c, 0x67, 0x62, 0x7a, 0x35, 0x74, 0x31, 0x49, 0x4f, 0x54, 0x58, + 0x49, 0x4d, 0x62, 0x62, 0x52, 0x52, 0x41, 0x4f, 0x39, 0x63, 0x52, 0x54, 0x50, 0x48, 0x75, 0x72, + 0x4c, 0x67, 0x53, 0x73, 0x45, 0x63, 0x37, 0x6e, 0x58, 0x6e, 0x35, 0x79, 0x43, 0x59, 0x37, 0x0a, + 0x68, 0x54, 0x2f, 0x34, 0x6c, 0x2f, 0x50, 0x61, 0x7a, 0x65, 0x70, 0x68, 0x70, 0x4e, 0x77, 0x6b, + 0x33, 0x44, 0x72, 0x31, 0x4d, 0x4b, 0x53, 0x4a, 0x70, 0x32, 0x42, 0x59, 0x69, 0x34, 0x73, 0x45, + 0x7a, 0x6a, 0x77, 0x4b, 0x69, 0x44, 0x4f, 0x41, 0x4b, 0x65, 0x67, 0x58, 0x6a, 0x52, 0x6f, 0x4d, + 0x6a, 0x79, 0x42, 0x64, 0x61, 0x6b, 0x56, 0x63, 0x67, 0x62, 0x35, 0x35, 0x6d, 0x77, 0x64, 0x7a, + 0x0a, 0x48, 0x30, 0x65, 0x36, 0x78, 0x64, 0x70, 0x64, 0x71, 0x45, 0x79, 0x49, 0x42, 0x6b, 0x4f, + 0x48, 0x39, 0x65, 0x51, 0x67, 0x32, 0x32, 0x73, 0x2b, 0x75, 0x68, 0x70, 0x39, 0x38, 0x56, 0x71, + 0x46, 0x41, 0x35, 0x7a, 0x6b, 0x52, 0x61, 0x32, 0x73, 0x74, 0x74, 0x35, 0x58, 0x36, 0x62, 0x76, + 0x53, 0x37, 0x4d, 0x62, 0x33, 0x47, 0x31, 0x42, 0x54, 0x66, 0x47, 0x4e, 0x4f, 0x7a, 0x4f, 0x5a, + 0x55, 0x0a, 0x42, 0x6f, 0x56, 0x4a, 0x2f, 0x30, 0x74, 0x50, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, + 0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x55, 0x52, 0x4e, 0x52, 0x4d, 0x78, 0x4d, 0x68, 0x62, 0x39, + 0x50, 0x47, 0x62, 0x69, 0x35, 0x7a, 0x71, 0x4d, 0x42, 0x69, 0x51, 0x70, 0x47, 0x76, 0x74, 0x41, + 0x46, 0x59, 0x64, 0x64, 0x53, 0x4d, 0x41, 0x58, 0x37, 0x6c, 0x31, 0x4e, 0x69, 0x56, 0x67, 0x56, + 0x37, 0x36, 0x0a, 0x42, 0x73, 0x77, 0x75, 0x78, 0x4f, 0x59, 0x72, 0x37, 0x45, 0x6d, 0x71, 0x4e, + 0x4d, 0x39, 0x66, 0x7a, 0x73, 0x5a, 0x49, 0x65, 0x76, 0x70, 0x39, 0x2b, 0x63, 0x66, 0x37, 0x4a, + 0x70, 0x77, 0x38, 0x59, 0x76, 0x35, 0x5a, 0x6e, 0x47, 0x5a, 0x63, 0x52, 0x38, 0x46, 0x57, 0x4a, + 0x71, 0x73, 0x6c, 0x77, 0x6c, 0x78, 0x66, 0x56, 0x58, 0x4a, 0x61, 0x34, 0x53, 0x6f, 0x48, 0x74, + 0x43, 0x58, 0x73, 0x0a, 0x4a, 0x4a, 0x53, 0x59, 0x6f, 0x70, 0x61, 0x49, 0x38, 0x34, 0x42, 0x6c, + 0x57, 0x4e, 0x77, 0x6a, 0x69, 0x43, 0x2f, 0x61, 0x34, 0x50, 0x4f, 0x43, 0x44, 0x6f, 0x63, 0x53, + 0x6a, 0x7a, 0x7a, 0x38, 0x68, 0x47, 0x63, 0x43, 0x47, 0x42, 0x6e, 0x2f, 0x38, 0x61, 0x4f, 0x4b, + 0x72, 0x74, 0x42, 0x52, 0x48, 0x46, 0x79, 0x7a, 0x46, 0x30, 0x72, 0x4d, 0x34, 0x66, 0x75, 0x6f, + 0x77, 0x61, 0x51, 0x57, 0x0a, 0x47, 0x71, 0x42, 0x77, 0x36, 0x43, 0x46, 0x41, 0x4a, 0x6a, 0x46, + 0x33, 0x64, 0x4e, 0x2f, 0x61, 0x4d, 0x66, 0x7a, 0x71, 0x35, 0x37, 0x42, 0x32, 0x67, 0x69, 0x67, + 0x49, 0x32, 0x36, 0x41, 0x4b, 0x39, 0x70, 0x62, 0x32, 0x5a, 0x4c, 0x74, 0x4f, 0x45, 0x59, 0x49, + 0x52, 0x2b, 0x46, 0x51, 0x56, 0x4b, 0x33, 0x57, 0x6f, 0x36, 0x75, 0x66, 0x2f, 0x48, 0x67, 0x59, + 0x4a, 0x47, 0x38, 0x2b, 0x75, 0x0a, 0x43, 0x33, 0x2f, 0x67, 0x70, 0x4d, 0x5a, 0x49, 0x58, 0x6a, + 0x67, 0x6b, 0x66, 0x30, 0x78, 0x74, 0x32, 0x41, 0x37, 0x39, 0x2f, 0x54, 0x74, 0x30, 0x37, 0x69, + 0x39, 0x62, 0x73, 0x5a, 0x4b, 0x54, 0x6a, 0x67, 0x78, 0x76, 0x2b, 0x73, 0x41, 0x70, 0x32, 0x69, + 0x79, 0x74, 0x6a, 0x6f, 0x6e, 0x34, 0x65, 0x74, 0x41, 0x4d, 0x49, 0x49, 0x49, 0x70, 0x58, 0x36, + 0x4c, 0x46, 0x75, 0x68, 0x6f, 0x68, 0x0a, 0x52, 0x54, 0x76, 0x6e, 0x45, 0x57, 0x2f, 0x4f, 0x5a, + 0x37, 0x4a, 0x70, 0x44, 0x32, 0x53, 0x35, 0x77, 0x50, 0x37, 0x4d, 0x54, 0x36, 0x48, 0x4c, 0x2b, + 0x72, 0x35, 0x50, 0x6c, 0x64, 0x52, 0x47, 0x39, 0x35, 0x63, 0x61, 0x39, 0x55, 0x47, 0x5a, 0x69, + 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x65, 0x72, 0x77, 0x66, 0x59, 0x63, 0x72, 0x37, 0x30, 0x75, + 0x51, 0x59, 0x55, 0x4d, 0x74, 0x32, 0x53, 0x0a, 0x66, 0x51, 0x54, 0x46, 0x31, 0x77, 0x39, 0x68, + 0x36, 0x66, 0x36, 0x75, 0x6d, 0x41, 0x77, 0x31, 0x45, 0x51, 0x31, 0x52, 0x42, 0x35, 0x71, 0x38, + 0x6b, 0x6a, 0x6d, 0x61, 0x41, 0x59, 0x62, 0x2b, 0x32, 0x2b, 0x75, 0x69, 0x59, 0x70, 0x4c, 0x53, + 0x4b, 0x64, 0x56, 0x67, 0x4a, 0x66, 0x44, 0x38, 0x67, 0x37, 0x49, 0x39, 0x32, 0x64, 0x76, 0x4f, + 0x78, 0x5a, 0x39, 0x66, 0x59, 0x6a, 0x73, 0x59, 0x0a, 0x6a, 0x56, 0x4a, 0x33, 0x6e, 0x68, 0x59, + 0x42, 0x44, 0x79, 0x6a, 0x73, 0x6c, 0x2b, 0x71, 0x2b, 0x73, 0x78, 0x68, 0x56, 0x48, 0x61, 0x37, + 0x44, 0x2f, 0x61, 0x44, 0x31, 0x66, 0x47, 0x4f, 0x48, 0x4a, 0x2b, 0x79, 0x4c, 0x44, 0x79, 0x75, + 0x49, 0x49, 0x41, 0x47, 0x4d, 0x79, 0x51, 0x31, 0x47, 0x51, 0x36, 0x30, 0x37, 0x48, 0x47, 0x30, + 0x56, 0x38, 0x61, 0x50, 0x69, 0x49, 0x34, 0x59, 0x47, 0x0a, 0x48, 0x37, 0x6b, 0x49, 0x49, 0x6b, + 0x31, 0x77, 0x37, 0x39, 0x52, 0x74, 0x46, 0x71, 0x67, 0x39, 0x6b, 0x48, 0x34, 0x68, 0x30, 0x4e, + 0x77, 0x48, 0x46, 0x77, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x30, 0x46, 0x6b, 0x66, 0x2f, 0x4f, 0x64, + 0x74, 0x48, 0x57, 0x6a, 0x6c, 0x72, 0x2f, 0x76, 0x54, 0x77, 0x68, 0x73, 0x4e, 0x36, 0x37, 0x66, + 0x54, 0x74, 0x2f, 0x4c, 0x62, 0x6d, 0x65, 0x53, 0x41, 0x45, 0x0a, 0x57, 0x5a, 0x39, 0x58, 0x79, + 0x74, 0x79, 0x4c, 0x64, 0x5a, 0x76, 0x46, 0x67, 0x2b, 0x64, 0x39, 0x4f, 0x55, 0x65, 0x31, 0x42, + 0x54, 0x31, 0x61, 0x41, 0x31, 0x56, 0x50, 0x72, 0x59, 0x65, 0x4c, 0x35, 0x69, 0x6d, 0x30, 0x52, + 0x6c, 0x78, 0x67, 0x57, 0x47, 0x53, 0x36, 0x65, 0x78, 0x67, 0x71, 0x6d, 0x73, 0x71, 0x2b, 0x41, + 0x79, 0x6c, 0x32, 0x38, 0x6f, 0x41, 0x57, 0x56, 0x2f, 0x73, 0x46, 0x0a, 0x4a, 0x45, 0x47, 0x71, + 0x52, 0x66, 0x6c, 0x48, 0x41, 0x32, 0x4f, 0x77, 0x72, 0x31, 0x62, 0x53, 0x63, 0x55, 0x6e, 0x55, + 0x6f, 0x76, 0x57, 0x54, 0x79, 0x72, 0x4c, 0x70, 0x30, 0x4a, 0x31, 0x52, 0x51, 0x57, 0x6d, 0x52, + 0x7a, 0x4d, 0x53, 0x4d, 0x71, 0x74, 0x34, 0x48, 0x65, 0x58, 0x6f, 0x67, 0x57, 0x4a, 0x6b, 0x73, + 0x62, 0x6e, 0x6f, 0x4c, 0x6d, 0x49, 0x39, 0x35, 0x56, 0x64, 0x69, 0x64, 0x0a, 0x58, 0x70, 0x4a, + 0x43, 0x64, 0x57, 0x79, 0x41, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x46, 0x68, 0x4b, 0x37, 0x41, 0x42, + 0x74, 0x56, 0x72, 0x74, 0x76, 0x6c, 0x54, 0x4a, 0x7a, 0x44, 0x4a, 0x6c, 0x6c, 0x69, 0x6e, 0x76, + 0x72, 0x44, 0x6f, 0x56, 0x54, 0x49, 0x78, 0x45, 0x55, 0x35, 0x6c, 0x6f, 0x77, 0x48, 0x61, 0x69, + 0x51, 0x4c, 0x46, 0x45, 0x79, 0x5a, 0x54, 0x5a, 0x6a, 0x2f, 0x71, 0x4f, 0x55, 0x0a, 0x6a, 0x54, + 0x52, 0x41, 0x67, 0x31, 0x68, 0x6a, 0x44, 0x2b, 0x42, 0x6b, 0x69, 0x73, 0x32, 0x45, 0x5a, 0x69, + 0x72, 0x52, 0x38, 0x36, 0x35, 0x6a, 0x65, 0x78, 0x4a, 0x31, 0x76, 0x31, 0x71, 0x33, 0x78, 0x67, + 0x66, 0x35, 0x6e, 0x56, 0x33, 0x6b, 0x4a, 0x65, 0x54, 0x52, 0x51, 0x31, 0x6c, 0x44, 0x5a, 0x35, + 0x56, 0x77, 0x42, 0x48, 0x68, 0x66, 0x57, 0x75, 0x2b, 0x61, 0x31, 0x31, 0x65, 0x69, 0x0a, 0x67, + 0x38, 0x36, 0x4c, 0x51, 0x45, 0x5a, 0x6a, 0x38, 0x6c, 0x6c, 0x67, 0x36, 0x69, 0x74, 0x2b, 0x37, + 0x2f, 0x4f, 0x74, 0x44, 0x4b, 0x2b, 0x54, 0x74, 0x4e, 0x67, 0x59, 0x48, 0x36, 0x37, 0x54, 0x36, + 0x79, 0x69, 0x48, 0x65, 0x55, 0x38, 0x62, 0x4f, 0x49, 0x33, 0x63, 0x57, 0x75, 0x36, 0x32, 0x47, + 0x4e, 0x7a, 0x4e, 0x6c, 0x45, 0x41, 0x58, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4d, 0x42, 0x58, 0x0a, + 0x43, 0x6e, 0x62, 0x78, 0x5a, 0x58, 0x7a, 0x4e, 0x65, 0x54, 0x42, 0x44, 0x34, 0x55, 0x6e, 0x6b, + 0x4f, 0x41, 0x67, 0x58, 0x6d, 0x51, 0x6b, 0x73, 0x4f, 0x67, 0x68, 0x56, 0x62, 0x45, 0x68, 0x68, + 0x51, 0x7a, 0x49, 0x51, 0x4e, 0x6b, 0x68, 0x69, 0x37, 0x64, 0x50, 0x77, 0x42, 0x43, 0x74, 0x6d, + 0x52, 0x72, 0x34, 0x37, 0x6d, 0x63, 0x50, 0x6a, 0x6d, 0x6f, 0x64, 0x46, 0x36, 0x2b, 0x6a, 0x75, + 0x0a, 0x2f, 0x76, 0x41, 0x43, 0x2f, 0x65, 0x6f, 0x68, 0x33, 0x59, 0x59, 0x68, 0x56, 0x38, 0x4c, + 0x43, 0x35, 0x58, 0x35, 0x6a, 0x79, 0x58, 0x6e, 0x6b, 0x7a, 0x39, 0x42, 0x4c, 0x6c, 0x67, 0x2f, + 0x51, 0x4b, 0x54, 0x70, 0x2f, 0x46, 0x31, 0x62, 0x42, 0x4d, 0x66, 0x35, 0x5a, 0x76, 0x4f, 0x58, + 0x70, 0x78, 0x63, 0x38, 0x63, 0x64, 0x72, 0x33, 0x32, 0x58, 0x5a, 0x50, 0x6f, 0x41, 0x76, 0x2b, + 0x7a, 0x0a, 0x74, 0x76, 0x66, 0x67, 0x54, 0x77, 0x57, 0x31, 0x34, 0x32, 0x34, 0x71, 0x61, 0x48, + 0x55, 0x79, 0x75, 0x38, 0x6b, 0x4b, 0x61, 0x58, 0x76, 0x58, 0x78, 0x54, 0x39, 0x4d, 0x79, 0x58, + 0x77, 0x41, 0x75, 0x4f, 0x70, 0x4c, 0x30, 0x36, 0x74, 0x5a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4e, + 0x75, 0x61, 0x68, 0x64, 0x65, 0x75, 0x61, 0x51, 0x6d, 0x6d, 0x6f, 0x6f, 0x51, 0x72, 0x70, 0x38, + 0x52, 0x45, 0x0a, 0x46, 0x6a, 0x63, 0x53, 0x6e, 0x7a, 0x64, 0x43, 0x41, 0x64, 0x50, 0x37, 0x79, + 0x74, 0x63, 0x58, 0x71, 0x77, 0x51, 0x62, 0x4c, 0x53, 0x64, 0x76, 0x48, 0x54, 0x73, 0x54, 0x57, + 0x71, 0x64, 0x6b, 0x67, 0x34, 0x55, 0x70, 0x51, 0x5a, 0x4c, 0x4d, 0x4f, 0x61, 0x37, 0x32, 0x4b, + 0x6b, 0x2b, 0x47, 0x42, 0x77, 0x67, 0x45, 0x2f, 0x6c, 0x39, 0x4f, 0x6f, 0x61, 0x32, 0x37, 0x65, + 0x69, 0x79, 0x45, 0x0a, 0x38, 0x4f, 0x75, 0x43, 0x65, 0x55, 0x41, 0x32, 0x37, 0x57, 0x6b, 0x55, + 0x54, 0x31, 0x31, 0x6f, 0x7a, 0x58, 0x65, 0x43, 0x72, 0x61, 0x55, 0x71, 0x4f, 0x55, 0x43, 0x4e, + 0x6e, 0x33, 0x37, 0x4a, 0x46, 0x30, 0x43, 0x31, 0x77, 0x51, 0x63, 0x4d, 0x7a, 0x76, 0x65, 0x69, + 0x69, 0x79, 0x45, 0x58, 0x33, 0x61, 0x67, 0x64, 0x51, 0x6f, 0x57, 0x67, 0x34, 0x55, 0x52, 0x67, + 0x37, 0x36, 0x79, 0x4d, 0x0a, 0x30, 0x48, 0x2f, 0x48, 0x45, 0x77, 0x73, 0x33, 0x46, 0x45, 0x56, + 0x55, 0x55, 0x35, 0x6a, 0x6f, 0x43, 0x69, 0x79, 0x51, 0x2f, 0x65, 0x65, 0x30, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a +}; + +#define APPLICATION_CERT_DER_LENGTH 1732 +UA_Byte APPLICATION_CERT_DER_DATA[1732] = { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, + 0x30, 0x6a, 0x43, 0x43, 0x41, 0x72, 0x71, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x43, 0x49, 0x69, 0x47, 0x4f, 0x65, 0x66, 0x54, 0x65, 0x4c, 0x4b, 0x4a, 0x70, 0x50, 0x69, 0x4c, + 0x39, 0x6e, 0x45, 0x41, 0x77, 0x33, 0x5a, 0x34, 0x44, 0x4b, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a, + 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x62, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, + 0x43, 0x52, 0x45, 0x55, 0x78, 0x44, 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, + 0x4d, 0x42, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x51, 0x30, 0x77, 0x43, 0x77, 0x59, + 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x52, 0x44, 0x61, 0x58, 0x52, 0x35, 0x0a, 0x4d, 0x52, + 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x78, 0x50, 0x63, 0x6d, + 0x64, 0x68, 0x62, 0x6d, 0x6c, 0x36, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x78, 0x45, 0x44, + 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x4d, 0x42, 0x30, 0x39, 0x79, 0x5a, 0x31, + 0x56, 0x75, 0x61, 0x58, 0x51, 0x78, 0x46, 0x7a, 0x41, 0x56, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, + 0x41, 0x4d, 0x4d, 0x44, 0x6b, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x57, 0x56, 0x6b, 0x61, + 0x57, 0x46, 0x30, 0x5a, 0x55, 0x4e, 0x42, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, + 0x44, 0x6b, 0x78, 0x4d, 0x54, 0x45, 0x30, 0x4d, 0x44, 0x41, 0x31, 0x4e, 0x46, 0x6f, 0x58, 0x44, + 0x54, 0x4d, 0x30, 0x4d, 0x44, 0x6b, 0x77, 0x4f, 0x54, 0x45, 0x30, 0x4d, 0x44, 0x41, 0x31, 0x0a, + 0x4e, 0x46, 0x6f, 0x77, 0x61, 0x7a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, + 0x42, 0x68, 0x4d, 0x43, 0x52, 0x45, 0x55, 0x78, 0x44, 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, + 0x42, 0x41, 0x67, 0x4d, 0x42, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x51, 0x30, 0x77, + 0x43, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x52, 0x44, 0x61, 0x58, 0x52, 0x35, + 0x0a, 0x4d, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x78, + 0x50, 0x63, 0x6d, 0x64, 0x68, 0x62, 0x6d, 0x6c, 0x36, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, + 0x78, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x4d, 0x42, 0x30, 0x39, + 0x79, 0x5a, 0x31, 0x56, 0x75, 0x61, 0x58, 0x51, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, + 0x56, 0x0a, 0x42, 0x41, 0x4d, 0x4d, 0x43, 0x30, 0x46, 0x77, 0x63, 0x47, 0x78, 0x70, 0x59, 0x32, + 0x46, 0x30, 0x61, 0x57, 0x39, 0x75, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, + 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, + 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, + 0x45, 0x41, 0x0a, 0x31, 0x46, 0x49, 0x31, 0x4a, 0x59, 0x66, 0x52, 0x62, 0x4b, 0x4b, 0x53, 0x4a, + 0x6a, 0x79, 0x6d, 0x51, 0x32, 0x48, 0x78, 0x62, 0x72, 0x2f, 0x31, 0x36, 0x52, 0x59, 0x56, 0x31, + 0x4f, 0x6e, 0x44, 0x72, 0x54, 0x74, 0x4a, 0x37, 0x6e, 0x73, 0x6a, 0x43, 0x6e, 0x6d, 0x53, 0x66, + 0x58, 0x7a, 0x38, 0x53, 0x75, 0x6b, 0x57, 0x7a, 0x53, 0x45, 0x58, 0x73, 0x35, 0x38, 0x73, 0x57, + 0x67, 0x2f, 0x67, 0x0a, 0x2f, 0x7a, 0x4a, 0x61, 0x78, 0x51, 0x30, 0x37, 0x4d, 0x77, 0x33, 0x36, + 0x69, 0x69, 0x32, 0x6a, 0x36, 0x54, 0x41, 0x53, 0x45, 0x51, 0x78, 0x37, 0x39, 0x6b, 0x45, 0x59, + 0x57, 0x4c, 0x45, 0x53, 0x46, 0x74, 0x47, 0x6f, 0x68, 0x61, 0x58, 0x36, 0x66, 0x50, 0x4e, 0x49, + 0x55, 0x72, 0x51, 0x51, 0x49, 0x6b, 0x66, 0x77, 0x6d, 0x44, 0x72, 0x4f, 0x35, 0x2b, 0x4f, 0x47, + 0x58, 0x37, 0x44, 0x36, 0x0a, 0x4c, 0x72, 0x6a, 0x75, 0x48, 0x38, 0x74, 0x34, 0x32, 0x61, 0x4f, + 0x38, 0x72, 0x75, 0x5a, 0x33, 0x69, 0x7a, 0x68, 0x68, 0x64, 0x71, 0x37, 0x72, 0x4b, 0x38, 0x37, + 0x67, 0x65, 0x57, 0x78, 0x4b, 0x4b, 0x67, 0x31, 0x35, 0x59, 0x47, 0x38, 0x2b, 0x62, 0x64, 0x53, + 0x44, 0x6b, 0x31, 0x79, 0x44, 0x47, 0x32, 0x30, 0x55, 0x51, 0x44, 0x76, 0x58, 0x45, 0x55, 0x7a, + 0x78, 0x37, 0x71, 0x79, 0x34, 0x0a, 0x45, 0x72, 0x42, 0x48, 0x4f, 0x35, 0x31, 0x35, 0x2b, 0x63, + 0x67, 0x6d, 0x4f, 0x34, 0x55, 0x2f, 0x2b, 0x4a, 0x66, 0x7a, 0x32, 0x73, 0x33, 0x71, 0x59, 0x61, + 0x54, 0x63, 0x4a, 0x4e, 0x77, 0x36, 0x39, 0x54, 0x43, 0x6b, 0x69, 0x61, 0x64, 0x67, 0x57, 0x49, + 0x75, 0x4c, 0x42, 0x4d, 0x34, 0x38, 0x43, 0x6f, 0x67, 0x7a, 0x67, 0x43, 0x6e, 0x6f, 0x46, 0x34, + 0x30, 0x61, 0x44, 0x49, 0x38, 0x67, 0x0a, 0x58, 0x57, 0x70, 0x46, 0x58, 0x49, 0x47, 0x2b, 0x65, + 0x5a, 0x73, 0x48, 0x63, 0x78, 0x39, 0x48, 0x75, 0x73, 0x58, 0x61, 0x58, 0x61, 0x68, 0x4d, 0x69, + 0x41, 0x5a, 0x44, 0x68, 0x2f, 0x58, 0x6b, 0x49, 0x4e, 0x74, 0x72, 0x50, 0x72, 0x6f, 0x61, 0x66, + 0x66, 0x46, 0x61, 0x68, 0x51, 0x4f, 0x63, 0x35, 0x45, 0x57, 0x74, 0x72, 0x4c, 0x62, 0x65, 0x56, + 0x2b, 0x6d, 0x37, 0x30, 0x75, 0x7a, 0x47, 0x0a, 0x39, 0x78, 0x74, 0x51, 0x55, 0x33, 0x78, 0x6a, + 0x54, 0x73, 0x7a, 0x6d, 0x56, 0x41, 0x61, 0x46, 0x53, 0x66, 0x39, 0x4c, 0x54, 0x77, 0x49, 0x44, + 0x41, 0x51, 0x41, 0x42, 0x6f, 0x32, 0x73, 0x77, 0x61, 0x54, 0x41, 0x6e, 0x42, 0x67, 0x4e, 0x56, + 0x48, 0x52, 0x45, 0x45, 0x49, 0x44, 0x41, 0x65, 0x68, 0x68, 0x78, 0x31, 0x63, 0x6d, 0x34, 0x36, + 0x64, 0x57, 0x35, 0x6a, 0x62, 0x32, 0x35, 0x6d, 0x0a, 0x61, 0x57, 0x64, 0x31, 0x63, 0x6d, 0x56, + 0x6b, 0x4f, 0x6d, 0x46, 0x77, 0x63, 0x47, 0x78, 0x70, 0x59, 0x32, 0x46, 0x30, 0x61, 0x57, 0x39, + 0x75, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, + 0x4e, 0x74, 0x2f, 0x68, 0x36, 0x7a, 0x4f, 0x62, 0x54, 0x76, 0x46, 0x33, 0x7a, 0x67, 0x75, 0x65, + 0x5a, 0x75, 0x44, 0x75, 0x38, 0x51, 0x43, 0x4a, 0x30, 0x0a, 0x6f, 0x7a, 0x41, 0x66, 0x42, 0x67, + 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x52, 0x6c, 0x76, 0x43, + 0x32, 0x55, 0x61, 0x31, 0x32, 0x64, 0x34, 0x59, 0x51, 0x31, 0x4f, 0x51, 0x79, 0x2b, 0x32, 0x43, + 0x76, 0x4c, 0x6e, 0x4c, 0x47, 0x72, 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, + 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x0a, 0x41, 0x41, 0x4f, 0x43, 0x41, + 0x67, 0x45, 0x41, 0x72, 0x62, 0x55, 0x4c, 0x61, 0x54, 0x44, 0x46, 0x39, 0x69, 0x30, 0x70, 0x66, + 0x34, 0x7a, 0x6d, 0x62, 0x55, 0x53, 0x69, 0x64, 0x34, 0x6f, 0x57, 0x7a, 0x6e, 0x45, 0x42, 0x77, + 0x55, 0x5a, 0x69, 0x6e, 0x37, 0x59, 0x69, 0x54, 0x76, 0x67, 0x38, 0x73, 0x34, 0x41, 0x31, 0x43, + 0x42, 0x76, 0x2f, 0x31, 0x75, 0x72, 0x75, 0x41, 0x62, 0x39, 0x6d, 0x0a, 0x4a, 0x52, 0x52, 0x59, + 0x35, 0x37, 0x61, 0x32, 0x65, 0x6c, 0x7a, 0x68, 0x31, 0x37, 0x45, 0x76, 0x51, 0x39, 0x72, 0x30, + 0x4a, 0x48, 0x6e, 0x49, 0x66, 0x73, 0x35, 0x41, 0x56, 0x68, 0x57, 0x2f, 0x4e, 0x45, 0x62, 0x6e, + 0x75, 0x5a, 0x73, 0x39, 0x59, 0x6a, 0x53, 0x6c, 0x6a, 0x55, 0x58, 0x74, 0x44, 0x64, 0x47, 0x63, + 0x6b, 0x6f, 0x48, 0x61, 0x34, 0x53, 0x4d, 0x55, 0x44, 0x44, 0x2f, 0x44, 0x0a, 0x76, 0x78, 0x4e, + 0x46, 0x44, 0x31, 0x6f, 0x72, 0x67, 0x2b, 0x79, 0x39, 0x75, 0x2b, 0x2f, 0x6b, 0x64, 0x52, 0x4d, + 0x64, 0x67, 0x66, 0x6d, 0x5a, 0x45, 0x69, 0x32, 0x59, 0x55, 0x62, 0x57, 0x68, 0x51, 0x53, 0x37, + 0x78, 0x34, 0x34, 0x31, 0x57, 0x73, 0x52, 0x30, 0x33, 0x32, 0x66, 0x4d, 0x54, 0x42, 0x44, 0x2b, + 0x64, 0x6b, 0x33, 0x38, 0x77, 0x42, 0x31, 0x4e, 0x2b, 0x42, 0x6e, 0x56, 0x54, 0x0a, 0x54, 0x43, + 0x50, 0x4c, 0x68, 0x43, 0x74, 0x6c, 0x76, 0x6d, 0x54, 0x46, 0x68, 0x34, 0x47, 0x48, 0x38, 0x71, + 0x48, 0x79, 0x57, 0x79, 0x77, 0x47, 0x48, 0x6a, 0x76, 0x38, 0x6e, 0x45, 0x45, 0x65, 0x70, 0x47, + 0x72, 0x68, 0x49, 0x49, 0x56, 0x66, 0x7a, 0x53, 0x57, 0x38, 0x51, 0x66, 0x53, 0x66, 0x4b, 0x6c, + 0x6a, 0x4d, 0x30, 0x36, 0x62, 0x76, 0x71, 0x4d, 0x58, 0x31, 0x2f, 0x46, 0x6b, 0x70, 0x0a, 0x38, + 0x76, 0x48, 0x41, 0x4e, 0x53, 0x67, 0x54, 0x69, 0x57, 0x2f, 0x4b, 0x58, 0x59, 0x7a, 0x33, 0x36, + 0x67, 0x71, 0x59, 0x57, 0x70, 0x44, 0x2f, 0x32, 0x41, 0x74, 0x57, 0x35, 0x75, 0x44, 0x4e, 0x58, + 0x56, 0x62, 0x76, 0x70, 0x5a, 0x48, 0x4b, 0x57, 0x59, 0x76, 0x34, 0x30, 0x67, 0x63, 0x73, 0x2f, + 0x59, 0x6b, 0x37, 0x66, 0x6a, 0x33, 0x38, 0x44, 0x65, 0x76, 0x4b, 0x46, 0x57, 0x35, 0x49, 0x0a, + 0x65, 0x71, 0x6c, 0x43, 0x55, 0x59, 0x6f, 0x50, 0x30, 0x2f, 0x41, 0x37, 0x47, 0x77, 0x43, 0x45, + 0x63, 0x58, 0x4a, 0x2f, 0x6b, 0x4a, 0x70, 0x5a, 0x50, 0x30, 0x45, 0x6d, 0x45, 0x37, 0x41, 0x51, + 0x6a, 0x6c, 0x61, 0x46, 0x6e, 0x44, 0x41, 0x51, 0x54, 0x71, 0x50, 0x57, 0x57, 0x2f, 0x4b, 0x72, + 0x73, 0x68, 0x2f, 0x61, 0x42, 0x65, 0x39, 0x2b, 0x5a, 0x41, 0x54, 0x46, 0x71, 0x50, 0x4f, 0x72, + 0x0a, 0x38, 0x32, 0x43, 0x43, 0x6d, 0x63, 0x4f, 0x59, 0x73, 0x32, 0x45, 0x2f, 0x2f, 0x6d, 0x77, + 0x30, 0x76, 0x59, 0x6d, 0x4c, 0x78, 0x68, 0x38, 0x4f, 0x61, 0x50, 0x37, 0x30, 0x62, 0x63, 0x4f, + 0x65, 0x65, 0x37, 0x64, 0x67, 0x51, 0x66, 0x4c, 0x53, 0x77, 0x75, 0x68, 0x71, 0x51, 0x44, 0x79, + 0x61, 0x44, 0x57, 0x2b, 0x67, 0x77, 0x75, 0x61, 0x61, 0x2f, 0x79, 0x7a, 0x71, 0x6b, 0x63, 0x4f, + 0x6c, 0x0a, 0x6c, 0x44, 0x30, 0x2f, 0x73, 0x51, 0x6e, 0x59, 0x68, 0x6a, 0x50, 0x53, 0x72, 0x62, + 0x49, 0x33, 0x36, 0x41, 0x54, 0x4a, 0x2f, 0x73, 0x36, 0x34, 0x4f, 0x41, 0x6e, 0x6d, 0x74, 0x70, + 0x4a, 0x53, 0x6d, 0x68, 0x51, 0x50, 0x67, 0x4a, 0x59, 0x63, 0x5a, 0x6a, 0x65, 0x32, 0x49, 0x6c, + 0x48, 0x42, 0x36, 0x77, 0x34, 0x38, 0x4c, 0x5a, 0x48, 0x34, 0x57, 0x79, 0x57, 0x4e, 0x30, 0x61, + 0x52, 0x4b, 0x0a, 0x32, 0x36, 0x70, 0x43, 0x53, 0x67, 0x49, 0x6a, 0x58, 0x74, 0x64, 0x7a, 0x43, + 0x47, 0x71, 0x48, 0x57, 0x53, 0x6c, 0x72, 0x55, 0x57, 0x59, 0x70, 0x6c, 0x77, 0x71, 0x46, 0x73, + 0x59, 0x33, 0x77, 0x6b, 0x34, 0x35, 0x6c, 0x58, 0x66, 0x53, 0x32, 0x30, 0x62, 0x6c, 0x45, 0x4d, + 0x30, 0x47, 0x41, 0x55, 0x7a, 0x2f, 0x56, 0x58, 0x33, 0x78, 0x58, 0x35, 0x6d, 0x51, 0x69, 0x64, + 0x41, 0x65, 0x72, 0x0a, 0x4a, 0x67, 0x47, 0x68, 0x46, 0x5a, 0x68, 0x2f, 0x55, 0x73, 0x56, 0x50, + 0x37, 0x41, 0x66, 0x4c, 0x4c, 0x6e, 0x75, 0x4f, 0x57, 0x68, 0x70, 0x35, 0x4d, 0x67, 0x58, 0x70, + 0x6b, 0x38, 0x72, 0x7a, 0x38, 0x50, 0x31, 0x4e, 0x69, 0x50, 0x4a, 0x49, 0x38, 0x6d, 0x57, 0x6c, + 0x6f, 0x55, 0x61, 0x75, 0x34, 0x4d, 0x6c, 0x35, 0x2b, 0x70, 0x71, 0x5a, 0x66, 0x76, 0x39, 0x57, + 0x35, 0x68, 0x76, 0x74, 0x0a, 0x48, 0x4a, 0x79, 0x31, 0x41, 0x59, 0x32, 0x2b, 0x35, 0x58, 0x53, + 0x70, 0x58, 0x7a, 0x2f, 0x36, 0x71, 0x66, 0x61, 0x4a, 0x41, 0x4d, 0x67, 0x2b, 0x38, 0x78, 0x71, + 0x66, 0x32, 0x64, 0x67, 0x55, 0x74, 0x77, 0x5a, 0x72, 0x42, 0x55, 0x2b, 0x5a, 0x52, 0x6e, 0x79, + 0x47, 0x6e, 0x32, 0x33, 0x6a, 0x67, 0x35, 0x67, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, + 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a +}; + _UA_END_DECLS #endif /* CERTIFICATES_H_ */ diff --git a/tests/encryption/check_certificategroup.c b/tests/encryption/check_certificategroup.c index 571464c56fd..0f0011b0a74 100644 --- a/tests/encryption/check_certificategroup.c +++ b/tests/encryption/check_certificategroup.c @@ -303,7 +303,7 @@ START_TEST(get_rejectedlist) { /* Secure client connect */ retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); - ck_assert_uint_eq(retval, UA_STATUSCODE_BADSECURITYCHECKSFAILED); + ck_assert_uint_eq(retval, UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE); UA_ByteString *rejectedList = NULL; size_t rejectedListSize = 0; diff --git a/tests/encryption/check_crl_validation.c b/tests/encryption/check_crl_validation.c new file mode 100644 index 00000000000..4065e90ccde --- /dev/null +++ b/tests/encryption/check_crl_validation.c @@ -0,0 +1,338 @@ +/* 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 2024 (c) Fraunhofer IOSB (Author: Noel Graf) + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "certificates.h" +#include "check.h" +#include "thread_wrapper.h" + +UA_Server *server; +UA_Boolean running; +THREAD_HANDLE server_thread; + +THREAD_CALLBACK(serverloop) { + while(running) + UA_Server_run_iterate(server, true); + return 0; +} + +static void setup1(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; + + UA_ByteString rootCa; + rootCa.length = ROOT_CERT_DER_LENGTH; + rootCa.data = ROOT_CERT_DER_DATA; + + UA_ByteString rootCaCrl; + rootCaCrl.length = ROOT_EMPTY_CRL_PEM_LENGTH; + rootCaCrl.data = ROOT_EMPTY_CRL_PEM_DATA; + + UA_ByteString intermediateCa; + intermediateCa.length = INTERMEDIATE_CERT_DER_LENGTH; + intermediateCa.data = INTERMEDIATE_CERT_DER_DATA; + + UA_ByteString intermediateCaCrl; + intermediateCaCrl.length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + intermediateCaCrl.data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = intermediateCa; + issuerList[1] = rootCa; + + /* Loading of a revocation list currently unsupported */ + size_t revocationListSize = 2; + UA_STACKARRAY(UA_ByteString, revocationList, revocationListSize); + revocationList[0] = rootCaCrl; + revocationList[1] = intermediateCaCrl; + + server = UA_Server_new(); + ck_assert(server != NULL); + 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"); + + UA_Server_run_startup(server); + THREAD_CREATE(server_thread, serverloop); +} + +static void setup2(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; + + UA_ByteString rootCa; + rootCa.length = ROOT_CERT_DER_LENGTH; + rootCa.data = ROOT_CERT_DER_DATA; + + UA_ByteString rootCaCrl; + rootCaCrl.length = ROOT_EMPTY_CRL_PEM_LENGTH; + rootCaCrl.data = ROOT_EMPTY_CRL_PEM_DATA; + + UA_ByteString intermediateCa; + intermediateCa.length = INTERMEDIATE_CERT_DER_LENGTH; + intermediateCa.data = INTERMEDIATE_CERT_DER_DATA; + + UA_ByteString intermediateCaCrl; + intermediateCaCrl.length = INTERMEDIATE_CRL_PEM_LENGTH; + intermediateCaCrl.data = INTERMEDIATE_CRL_PEM_DATA; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = intermediateCa; + issuerList[1] = rootCa; + + /* Loading of a revocation list currently unsupported */ + size_t revocationListSize = 2; + UA_STACKARRAY(UA_ByteString, revocationList, revocationListSize); + revocationList[0] = rootCaCrl; + revocationList[1] = intermediateCaCrl; + + server = UA_Server_new(); + ck_assert(server != NULL); + 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"); + + UA_Server_run_startup(server); + THREAD_CREATE(server_thread, serverloop); +} + +static void setup3(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; + + UA_ByteString rootCa; + rootCa.length = ROOT_CERT_DER_LENGTH; + rootCa.data = ROOT_CERT_DER_DATA; + + UA_ByteString rootCaCrl; + rootCaCrl.length = ROOT_CRL_PEM_LENGTH; + rootCaCrl.data = ROOT_CRL_PEM_DATA; + + UA_ByteString intermediateCa; + intermediateCa.length = INTERMEDIATE_CERT_DER_LENGTH; + intermediateCa.data = INTERMEDIATE_CERT_DER_DATA; + + UA_ByteString intermediateCaCrl; + intermediateCaCrl.length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + intermediateCaCrl.data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = rootCa; + issuerList[1] = intermediateCa; + + /* Loading of a revocation list currently unsupported */ + size_t revocationListSize = 2; + UA_STACKARRAY(UA_ByteString, revocationList, revocationListSize); + revocationList[0] = rootCaCrl; + revocationList[1] = intermediateCaCrl; + + server = UA_Server_new(); + ck_assert(server != NULL); + 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"); + + 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_valid) { +/* Load certificate and private key */ + UA_ByteString certificate; + certificate.length = APPLICATION_CERT_DER_LENGTH; + certificate.data = APPLICATION_CERT_DER_DATA; + ck_assert_uint_ne(certificate.length, 0); + + UA_ByteString privateKey; + privateKey.length = APPLICATION_KEY_DER_LENGTH; + privateKey.data = APPLICATION_KEY_DER_DATA; + ck_assert_uint_ne(privateKey.length, 0); + + /* Load the trustlist */ + UA_ByteString *trustList = NULL; + size_t trustListSize = 0; + UA_ByteString *revocationList = NULL; + size_t revocationListSize = 0; + + /* Secure client initialization */ + UA_Client *client = UA_Client_new(); + UA_ClientConfig *cc = UA_Client_getConfig(client); + UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, + trustList, trustListSize, + revocationList, revocationListSize); + cc->certificateVerification.clear(&cc->certificateVerification); + UA_CertificateGroup_AcceptAll(&cc->certificateVerification); + cc->securityPolicyUri = + UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); + ck_assert(client != NULL); + + /* Secure client connect */ + UA_StatusCode 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_clear(&val); + + UA_Client_disconnect(client); + UA_Client_delete(client); +} +END_TEST + +START_TEST(encryption_connect_revoked) { + UA_ByteString certificate; + certificate.length = APPLICATION_CERT_DER_LENGTH; + certificate.data = APPLICATION_CERT_DER_DATA; + ck_assert_uint_ne(certificate.length, 0); + + UA_ByteString privateKey; + privateKey.length = APPLICATION_KEY_DER_LENGTH; + privateKey.data = APPLICATION_KEY_DER_DATA; + ck_assert_uint_ne(privateKey.length, 0); + + /* Load the trustlist */ + UA_ByteString *trustList = NULL; + size_t trustListSize = 0; + UA_ByteString *revocationList = NULL; + size_t revocationListSize = 0; + + /* Secure client initialization */ + UA_Client *client = UA_Client_new(); + UA_ClientConfig *cc = UA_Client_getConfig(client); + UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, + trustList, trustListSize, + revocationList, revocationListSize); + cc->certificateVerification.clear(&cc->certificateVerification); + UA_CertificateGroup_AcceptAll(&cc->certificateVerification); + cc->securityPolicyUri = + UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); + ck_assert(client != NULL); + + /* Secure client connect */ + UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); + ck_assert_uint_eq(retval, UA_STATUSCODE_BADSECURITYCHECKSFAILED); + + UA_Client_disconnect(client); + UA_Client_delete(client); +} +END_TEST + +static Suite* testSuite_encryption(void) { + Suite *s = suite_create("Certificate Revocation List"); + TCase *tc_encryption_valid = tcase_create("Certificate Revocation Valid"); + tcase_add_checked_fixture(tc_encryption_valid, setup1, teardown); + TCase *tc_encryption_revoked = tcase_create("Certificate Revocation Revoked"); + tcase_add_checked_fixture(tc_encryption_revoked, setup2, teardown); + TCase *tc_encryption_revoked2 = tcase_create("Certificate Revocation Revoked2"); + tcase_add_checked_fixture(tc_encryption_revoked2, setup3, teardown); +#ifdef UA_ENABLE_ENCRYPTION + tcase_add_test(tc_encryption_valid, encryption_connect_valid); + tcase_add_test(tc_encryption_revoked, encryption_connect_revoked); + tcase_add_test(tc_encryption_revoked2, encryption_connect_revoked); +#endif /* UA_ENABLE_ENCRYPTION */ + suite_add_tcase(s,tc_encryption_valid); + suite_add_tcase(s,tc_encryption_revoked); + suite_add_tcase(s,tc_encryption_revoked2); + 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; +} diff --git a/tests/pubsub/check_pubsub_sks_client.c b/tests/pubsub/check_pubsub_sks_client.c index 721c1ad2c6b..c80499beb4d 100644 --- a/tests/pubsub/check_pubsub_sks_client.c +++ b/tests/pubsub/check_pubsub_sks_client.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "test_helpers.h" #include "ua_pubsub.h" @@ -149,10 +150,23 @@ skssetup(void) { privateKey.length = KEY_DER_LENGTH; privateKey.data = KEY_DER_DATA; - size_t trustListSize = 0; - UA_ByteString *trustList = NULL; - size_t issuerListSize = 0; - UA_ByteString *issuerList = NULL; + UA_ByteString rootCa = {ROOT_CERT_DER_LENGTH, ROOT_CERT_DER_DATA}; + UA_ByteString rootCaCrl = {ROOT_CRL_PEM_LENGTH, ROOT_CRL_PEM_DATA}; + UA_ByteString intermediateCa = {INTERMEDIATE_CERT_DER_LENGTH, INTERMEDIATE_CERT_DER_DATA}; + UA_ByteString intermediateCaCrl = {INTERMEDIATE_EMPTY_CRL_PEM_LENGTH, INTERMEDIATE_EMPTY_CRL_PEM_DATA}; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = rootCa; + issuerList[1] = intermediateCa; + UA_ByteString *revocationList = NULL; size_t revocationListSize = 0; @@ -456,12 +470,12 @@ newEncryptedClientConfig(const char *username, const char *password) { /* Load certificate and private key */ UA_ByteString certificate; - certificate.length = CERT_DER_LENGTH; - certificate.data = CERT_DER_DATA; + certificate.length = APPLICATION_CERT_DER_LENGTH; + certificate.data = APPLICATION_CERT_DER_DATA; UA_ByteString privateKey; - privateKey.length = KEY_DER_LENGTH; - privateKey.data = KEY_DER_DATA; + privateKey.length = APPLICATION_KEY_DER_LENGTH; + privateKey.data = APPLICATION_KEY_DER_DATA; /* Secure client initialization */ @@ -474,6 +488,8 @@ newEncryptedClientConfig(const char *username, const char *password) { cc->securityPolicyUri = UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); + UA_CertificateVerification_AcceptAll(&cc->certificateVerification); + UA_UserNameIdentityToken* identityToken = UA_UserNameIdentityToken_new(); identityToken->userName = UA_STRING_ALLOC(username); identityToken->password = UA_STRING_ALLOC(password); diff --git a/tests/pubsub/check_pubsub_sks_pull.c b/tests/pubsub/check_pubsub_sks_pull.c index d58a35cfdee..cbb29d4e9c8 100644 --- a/tests/pubsub/check_pubsub_sks_pull.c +++ b/tests/pubsub/check_pubsub_sks_pull.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "test_helpers.h" #include "ua_pubsub.h" @@ -114,12 +115,27 @@ setup(void) { privateKey.length = KEY_DER_LENGTH; privateKey.data = KEY_DER_DATA; - size_t trustListSize = 0; - UA_ByteString *trustList = NULL; - size_t issuerListSize = 0; - UA_ByteString *issuerList = NULL; + UA_ByteString rootCa = {ROOT_CERT_DER_LENGTH, ROOT_CERT_DER_DATA}; + UA_ByteString rootCaCrl = {ROOT_CRL_PEM_LENGTH, ROOT_CRL_PEM_DATA}; + UA_ByteString intermediateCa = {INTERMEDIATE_CERT_DER_LENGTH, INTERMEDIATE_CERT_DER_DATA}; + UA_ByteString intermediateCaCrl = {INTERMEDIATE_EMPTY_CRL_PEM_LENGTH, INTERMEDIATE_EMPTY_CRL_PEM_DATA}; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = rootCa; + issuerList[1] = intermediateCa; + UA_ByteString *revocationList = NULL; size_t revocationListSize = 0; + + UA_StatusCode retVal = UA_STATUSCODE_GOOD; sksServer = UA_Server_newForUnitTestWithSecurityPolicies(4840, &certificate, &privateKey, trustList, trustListSize, @@ -194,13 +210,12 @@ encyrptedclientconnect(UA_Client *client) { /* Load certificate and private key */ UA_ByteString certificate; - certificate.length = CERT_DER_LENGTH; - certificate.data = CERT_DER_DATA; - ck_assert_uint_ne(certificate.length, 0); + certificate.length = APPLICATION_CERT_DER_LENGTH; + certificate.data = APPLICATION_CERT_DER_DATA; UA_ByteString privateKey; - privateKey.length = KEY_DER_LENGTH; - privateKey.data = KEY_DER_DATA; + privateKey.length = APPLICATION_KEY_DER_LENGTH; + privateKey.data = APPLICATION_KEY_DER_DATA; ck_assert_uint_ne(privateKey.length, 0); /* Secure client initialization */ @@ -214,6 +229,8 @@ encyrptedclientconnect(UA_Client *client) { UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); ck_assert(client != NULL); + UA_CertificateVerification_AcceptAll(&cc->certificateVerification); + return UA_STATUSCODE_GOOD; } diff --git a/tests/pubsub/check_pubsub_sks_push.c b/tests/pubsub/check_pubsub_sks_push.c index 7699de7f380..dfb7536aa7e 100644 --- a/tests/pubsub/check_pubsub_sks_push.c +++ b/tests/pubsub/check_pubsub_sks_push.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "test_helpers.h" #include "../encryption/certificates.h" @@ -76,14 +77,12 @@ encyrptedclientconnect(UA_Client *client) { /* Load certificate and private key */ UA_ByteString certificate; - certificate.length = CERT_DER_LENGTH; - certificate.data = CERT_DER_DATA; - ck_assert_uint_ne(certificate.length, 0); + certificate.length = APPLICATION_CERT_DER_LENGTH; + certificate.data = APPLICATION_CERT_DER_DATA; UA_ByteString privateKey; - privateKey.length = KEY_DER_LENGTH; - privateKey.data = KEY_DER_DATA; - ck_assert_uint_ne(privateKey.length, 0); + privateKey.length = APPLICATION_KEY_DER_LENGTH; + privateKey.data = APPLICATION_KEY_DER_DATA; /* Secure client initialization */ UA_ClientConfig *cc = UA_Client_getConfig(client); @@ -96,6 +95,8 @@ encyrptedclientconnect(UA_Client *client) { UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); ck_assert(client != NULL); + UA_CertificateVerification_AcceptAll(&cc->certificateVerification); + /* Secure client connect */ return UA_Client_connect(client, "opc.tcp://localhost:4840"); } @@ -197,10 +198,23 @@ setup(void) { privateKey.length = KEY_DER_LENGTH; privateKey.data = KEY_DER_DATA; - size_t trustListSize = 0; - UA_ByteString *trustList = NULL; - size_t issuerListSize = 0; - UA_ByteString *issuerList = NULL; + UA_ByteString rootCa = {ROOT_CERT_DER_LENGTH, ROOT_CERT_DER_DATA}; + UA_ByteString rootCaCrl = {ROOT_CRL_PEM_LENGTH, ROOT_CRL_PEM_DATA}; + UA_ByteString intermediateCa = {INTERMEDIATE_CERT_DER_LENGTH, INTERMEDIATE_CERT_DER_DATA}; + UA_ByteString intermediateCaCrl = {INTERMEDIATE_EMPTY_CRL_PEM_LENGTH, INTERMEDIATE_EMPTY_CRL_PEM_DATA}; + + /* Load the trustlist */ + size_t trustListSize = 2; + UA_STACKARRAY(UA_ByteString, trustList, trustListSize); + trustList[0] = intermediateCa; + trustList[1] = rootCa; + + /* Load the issuerList */ + size_t issuerListSize = 2; + UA_STACKARRAY(UA_ByteString, issuerList, issuerListSize); + issuerList[0] = rootCa; + issuerList[1] = intermediateCa; + UA_ByteString *revocationList = NULL; size_t revocationListSize = 0; diff --git a/tests/server/check_services_attributes.c b/tests/server/check_services_attributes.c index 0a22b110d6a..97c5ec1f19e 100644 --- a/tests/server/check_services_attributes.c +++ b/tests/server/check_services_attributes.c @@ -711,15 +711,45 @@ START_TEST(WriteSingleAttributeBrowseName) { } END_TEST START_TEST(WriteSingleAttributeDisplayName) { + /* Write a new locale. The server continues to respond with the old locale. */ UA_WriteValue wValue; UA_WriteValue_init(&wValue); - UA_LocalizedText testValue = UA_LOCALIZEDTEXT("en-EN", "the.answer"); + UA_LocalizedText testValue = UA_LOCALIZEDTEXT("en-EN", "the.answer.123"); UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); wValue.value.hasValue = true; wValue.nodeId = UA_NODEID_STRING(1, "the.answer"); wValue.attributeId = UA_ATTRIBUTEID_DISPLAYNAME; UA_StatusCode retval = UA_Server_write(server, &wValue); ck_assert_int_eq(retval, UA_STATUSCODE_GOOD); + + /* Read back the display name and compare. We continue to receive the original locale. */ + UA_ReadValueId rvi; + UA_ReadValueId_init(&rvi); + rvi.nodeId = UA_NODEID_STRING(1, "the.answer"); + rvi.attributeId = UA_ATTRIBUTEID_DISPLAYNAME; + UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER); + ck_assert(UA_Variant_hasScalarType(&resp.value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT])); + ck_assert(UA_order(&testValue, resp.value.data, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) != UA_ORDER_EQ); + UA_DataValue_clear(&resp); + + /* Update the original locale. The server continues to respond with the old locale. */ + UA_WriteValue_init(&wValue); + testValue = UA_LOCALIZEDTEXT("locale", "the.answer.123"); + UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); + wValue.value.hasValue = true; + wValue.nodeId = UA_NODEID_STRING(1, "the.answer"); + wValue.attributeId = UA_ATTRIBUTEID_DISPLAYNAME; + retval = UA_Server_write(server, &wValue); + ck_assert_int_eq(retval, UA_STATUSCODE_GOOD); + + /* Read back the new display name and compare */ + UA_ReadValueId_init(&rvi); + rvi.nodeId = UA_NODEID_STRING(1, "the.answer"); + rvi.attributeId = UA_ATTRIBUTEID_DISPLAYNAME; + resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER); + ck_assert(UA_Variant_hasScalarType(&resp.value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT])); + ck_assert(UA_order(&testValue, resp.value.data, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) == UA_ORDER_EQ); + UA_DataValue_clear(&resp); } END_TEST START_TEST(WriteSingleAttributeDescription) {